Prechádzať zdrojové kódy

docs: design network library layering

Eric Streit 3 dní pred
rodič
commit
2a3f7e7e66
2 zmenil súbory, kde vykonal 314 pridanie a 10 odobranie
  1. 2 2
      docs/INDEX.md
  2. 312 8
      docs/future-work-2026-10-25.md

+ 2 - 2
docs/INDEX.md

@@ -37,8 +37,8 @@ bisecting *why* a decision was made, not for reading end-to-end).
 - **`future-work-2026-10-25.md`** — TBITSIZE, ADDRESS arithmetic, set
   ordering, complex types, pragmas (TopSpeed vs portable), UTF-8 string
   libraries, collections and the TopSpeed B-tree Toolkit, communications,
-  pyserial, ModBase, PIM vs ISO coroutines, external assembly,
-  dynamic-set design and suggested order.
+  pyserial, ModBase, network-library design, PIM vs ISO coroutines,
+  external assembly, dynamic-set design and suggested order.
 
 ## Designs / running records
 

+ 312 - 8
docs/future-work-2026-10-25.md

@@ -4,8 +4,9 @@ This note records the design discussions from 2026-10-25 so the
 questions do not have to be re-derived later.  It covers `TBITSIZE`,
 address arithmetic, set ordering, complex types, pragmas, UTF-8 string
 libraries, collections, the TopSpeed B-tree Toolkit, communications,
-pyserial, ModBase, PIM versus ISO coroutines, external assembly, and the
-dynamic-set design.  It is not a commitment to implement everything.
+pyserial, ModBase, network-library design, PIM versus ISO coroutines,
+external assembly, and the dynamic-set design.  It is not a commitment
+to implement everything.
 
 **State at the time of writing:** suite 310/310, one-shot fixpoint OK
 (3,845,439 bytes), per-object fixpoint OK (11 objects), corpus
@@ -1334,7 +1335,309 @@ Recommendation:
 
 ---
 
-## 12. Suggested order of future work
+## 12. Network library design
+
+V3 currently has no socket/network support.  `lib/iso/IOChan` is a
+file/stdio-style channel API with no addresses, timeouts, non-blocking
+mode or datagrams, so it can be a convenience bridge but not the primary
+network API.
+
+The network library should be layered:
+
+```text
+Application
+  HTTP / WebSocket / custom protocols
+        |
+TLS (optional)
+        |
+Transport  (connected byte stream or datagram)
+        |
+Net        (addresses, DNS, TCP/UDP sockets, listeners)
+        |
+C shim / OS sockets
+```
+
+`Transport` is shared with the communications work:
+
+- serial transport
+- TCP transport
+- loopback transport
+- TLS transport wrapping another transport
+
+Protocol modules should depend only on `Transport`, never directly on
+`Socket`.
+
+### 12.1 Core API shape
+
+Use opaque handles; do not expose file descriptors or `sockaddr`.
+
+```modula2
+DEFINITION MODULE Net;
+
+TYPE
+  Family = (IPv4, IPv6);
+  Kind   = (Stream, Datagram);
+  ShutdownMode = (StopReading, StopWriting, StopBoth);
+
+  Status = (Ok, WouldBlock, Timeout, Closed, Refused,
+            Unreachable, BadAddress, NotFound,
+            PermissionDenied, OutOfResources,
+            NetworkError, UnknownError);
+
+  Socket;
+  Address;
+
+PROCEDURE Resolve(host : ARRAY OF CHAR; port : CARDINAL;
+                  family : Family; kind : Kind;
+                  VAR addr : Address) : Status;
+
+PROCEDURE Listen(addr : Address; backlog : CARDINAL;
+                 VAR listener : Socket) : Status;
+
+PROCEDURE Accept(listener : Socket;
+                 VAR conn : Socket;
+                 VAR peer : Address) : Status;
+
+PROCEDURE Connect(addr : Address; timeoutMS : CARDINAL;
+                  VAR conn : Socket) : Status;
+
+PROCEDURE Read(conn : Socket; VAR buf : ARRAY OF BYTE;
+               max, timeoutMS : CARDINAL;
+               VAR n : CARDINAL) : Status;
+
+PROCEDURE Write(conn : Socket; VAR buf : ARRAY OF BYTE;
+                len, timeoutMS : CARDINAL;
+                VAR n : CARDINAL) : Status;
+
+PROCEDURE WriteAll(conn : Socket; VAR buf : ARRAY OF BYTE;
+                   len, timeoutMS : CARDINAL;
+                   VAR written : CARDINAL) : Status;
+
+PROCEDURE Shutdown(conn : Socket; mode : ShutdownMode);
+PROCEDURE Close(VAR s : Socket);
+
+PROCEDURE LocalAddress(s : Socket; VAR a : Address) : Status;
+PROCEDURE PeerAddress(s : Socket; VAR a : Address) : Status;
+PROCEDURE AddressToString(a : Address; VAR s : ARRAY OF CHAR);
+PROCEDURE LastError(s : Socket) : CARDINAL;
+```
+
+Rules:
+
+- `Socket` and `Address` are opaque.
+- `ARRAY OF BYTE` is the binary buffer type; text helpers wrap it.
+- `Read` and `Write` may return short counts.
+- `WriteAll` loops over partial writes with a timeout.
+- Timeouts are milliseconds, not floating-point seconds.
+- `WouldBlock` is a normal result in non-blocking mode.
+- `Closed` means orderly shutdown or peer close.
+- `LastError` returns the OS error code for diagnostics.
+
+### 12.2 Addresses and DNS
+
+Do not model addresses as a single `CARDINAL` IPv4 value.
+
+Use an opaque `Address` supporting:
+
+- IPv4 and IPv6;
+- textual host names;
+- numeric addresses;
+- port numbers;
+- address-to-string and string-to-address conversion.
+
+Use `getaddrinfo`, not `gethostbyname`.  A resolver may return several
+addresses; `Connect` should be able to try them in order.
+
+For listening sockets:
+
+- use `AI_PASSIVE` for wildcard binds;
+- handle IPv4/IPv6 dual-stack and optional `IPV6_V6ONLY`;
+- use `SO_REUSEADDR` for restart;
+- require an explicit wildcard bind for public interfaces.
+
+A useful security default: servers bind to loopback unless the caller
+explicitly asks for a public interface.
+
+Initial limitation: `getaddrinfo` is blocking and has no timeout.  An
+asynchronous resolver can be added later.
+
+### 12.3 TCP and UDP
+
+TCP:
+
+- `Listen`, `Accept`, `Connect`;
+- stream reads/writes with timeouts;
+- partial writes;
+- graceful `Shutdown`;
+- optional `SO_KEEPALIVE` and `TCP_NODELAY`;
+- no automatic reconnection.
+
+UDP:
+
+- `SendTo` / `RecvFrom`;
+- datagram boundaries preserved;
+- maximum datagram size reported clearly;
+- optional connected UDP;
+- no stream semantics.
+
+Keep TCP and UDP wrappers separate publicly even if they share a core
+socket module.
+
+### 12.4 Concurrency and event loop
+
+Do not require threads.
+
+Phase 1:
+
+- blocking sockets with explicit timeouts;
+- `poll` in the C shim;
+- one connection or request at a time is allowed.
+
+Phase 2:
+
+- non-blocking sockets;
+- a `PollSet` abstraction:
+
+```modula2
+TYPE
+  Event = SET OF (Readable, Writable, Error);
+
+PROCEDURE Init(VAR p : PollSet);
+PROCEDURE Add(VAR p : PollSet; s : Socket; events : Event);
+PROCEDURE Remove(VAR p : PollSet; s : Socket);
+PROCEDURE Wait(VAR p : PollSet; timeoutMS : CARDINAL;
+               VAR ready : CARDINAL) : Status;
+PROCEDURE Events(p : PollSet; s : Socket) : Event;
+```
+
+Phase 3:
+
+- integrate `PollSet` with PIM coroutines or an event loop;
+- a connection handler can yield while waiting for I/O;
+- no hidden thread pool.
+
+Use `poll` first; `epoll` is an optimization, not a public API
+requirement.
+
+### 12.5 Errors and security
+
+Use status codes as the default; fatal errors and uncaught exceptions
+are not the normal path.
+
+The shim must:
+
+- retry `EINTR`;
+- handle `EINPROGRESS` for non-blocking connect;
+- translate `EAGAIN`/`EWOULDBLOCK` to `WouldBlock`;
+- handle `SIGPIPE` with `MSG_NOSIGNAL` or an ignored signal;
+- never leak descriptors on failed connect/accept/listen;
+- preserve an OS error code for diagnostics.
+
+### 12.6 TLS and HTTP
+
+Do not implement TLS.  Use OpenSSL or mbedTLS through a C shim.
+
+TLS module:
+
+```text
+Tls.Connect(transport, hostname, ...)
+Tls.Read
+Tls.Write
+Tls.Close
+```
+
+Defaults:
+
+- certificate verification enabled;
+- SNI;
+- hostname verification;
+- no fallback to plaintext;
+- clear errors for certificate failures.
+
+HTTP is later:
+
+- HTTP/1.1 client first;
+- headers and `Content-Length`;
+- chunked transfer encoding;
+- keep-alive;
+- redirects and size limits;
+- no HTTP/2 initially.
+
+WebSocket is later still.
+
+### 12.7 Platform strategy
+
+Start with POSIX/Linux:
+
+- C shim over `socket`, `bind`, `listen`, `accept`, `connect`,
+  `send`, `recv`, `poll`, `getaddrinfo`, `setsockopt`, `shutdown`,
+  `close`;
+- hide `sockaddr_storage`, `addrinfo`, `fd_set` and `pollfd` behind the
+  shim.
+
+Later add a Windows Winsock2 backend behind the same API.
+
+Do not expose `sockaddr`, `fd_set`, `pollfd` or raw file descriptors in
+Modula-2.
+
+### 12.8 Suggested module layout
+
+```text
+runtime/syslib/net.c          POSIX C shim
+lib/common/Net.def/.mod       addresses, DNS, sockets, status
+lib/common/Transport.def/.mod connected byte transport
+lib/common/Poll.def/.mod      readiness/event API
+lib/common/Loopback.def/.mod  deterministic tests
+lib/common/Tls.def/.mod       optional, OpenSSL/mbedTLS
+lib/common/Http.def/.mod      optional, later
+```
+
+Possible names:
+
+- `Net` — socket/address layer
+- `Tcp` / `Udp` — protocol-specific wrappers
+- `Poll` — event readiness
+- `Transport` — shared with serial
+- `Tls` — optional security layer
+- `Http` — optional application protocol
+
+### 12.9 Tests
+
+Use loopback and ephemeral ports only:
+
+- TCP client/server on `127.0.0.1` and `::1`;
+- UDP send/receive;
+- partial read/write;
+- connect timeout and refused connection;
+- DNS failure and bad address;
+- peer close and local shutdown;
+- `SIGPIPE` / write-after-close;
+- large transfers;
+- multiple simultaneous sockets;
+- poll timeout;
+- listener restart with `SO_REUSEADDR`;
+- TLS certificate failure and success later.
+
+No external network is required for the suite.
+
+### 12.10 Suggested order within network work
+
+1. POSIX socket shim and `Net` status/address API.
+2. TCP client/server.
+3. UDP.
+4. `Poll` and non-blocking sockets.
+5. `Transport` integration with serial/loopback.
+6. TLS via OpenSSL or mbedTLS.
+7. HTTP/1.1 client, then server.
+8. WebSocket or other protocols if needed.
+
+Do not start with HTTP or TLS.  Do not expose raw sockets or
+`sockaddr`.  Do not require threads.  Reuse the `Transport` abstraction
+so serial, TCP, loopback and TLS share one protocol-facing interface.
+
+---
+
+## 13. Suggested order of future work
 
 1. `TBITSIZE` (small, standard-facing).
 2. `ADDADR`/`SUBADR`/`DIFADR` (small, ISO SYSTEM).
@@ -1349,11 +1652,12 @@ Recommendation:
    `BTreeMap`; persistent `BTreeFile` last.
 8. Communications: `Serial`/`Transport` first; protocols and terminal
    emulation optional.
-9. Database: SQLite binding or typed B-tree table layer; dBase III only
-   if required.
-10. ISO `COROUTINES` subset, then interrupt/protection layer.
-11. Dynamic `SET CONST` and deep composite copies.
-12. Parser error recovery and diagnostics.
+9. Network: `Net`/`Transport`, TCP/UDP, `Poll`, then optional TLS/HTTP.
+10. Database: SQLite binding or typed B-tree table layer; dBase III
+    only if required.
+11. ISO `COROUTINES` subset, then interrupt/protection layer.
+12. Dynamic `SET CONST` and deep composite copies.
+13. Parser error recovery and diagnostics.
 
 External assembly needs no compiler work; document it as the supported
 low-level escape hatch.