@ai-ecoverse/slicc-kernel 1.164.0 → 1.164.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -538,7 +538,7 @@ The module's default export (or its `main` export) is called with a context and
538
538
  - A connection's `tls` is `{ path: 'kernel', protocol, cipher ({ name, standardName, version }, as a client's; [#1500](https://github.com/ai-ecoverse/slicc-kernel/issues/1500)), alpnProtocol, servername (the SNI the client sent, or ''), authorized (whether a client certificate verified), authorizationError?, peerCertificates (the client's chain) }`.
539
539
  - On a `listen({ tls })` listener, the kernel handshakes accepted connections concurrently, from the first `accept` on, and `accept` (and `for await`) yields each as its handshake finishes, so a client that connects and stays silent doesn't hold up the next. It holds at most `backlog` (up to 64) connections in a handshake or handshaken but not yet taken; beyond that it stops accepting, leaving the rest in the kernel's backlog, until one finishes or is taken. A connection whose handshake fails is closed and never yielded. `secure()` rejects instead.
540
540
  - `handshakeTimeout` (milliseconds, 120000 by default, as Node's) ends a handshake that hasn't finished with `ERR_TLS_HANDSHAKE_TIMEOUT`. A listener closes that connection. After `secure()` rejects, the connection stays open and is the program's to answer or close, as with Node's `tlsClientError` ([#1504](https://github.com/ai-ecoverse/slicc-kernel/issues/1504)).
541
- - A client that sends a plain HTTP request instead of a ClientHello fails the handshake with `ERR_SSL_HTTP_REQUEST`, as in Node. A client that resets during the handshake fails it with `ECONNRESET` and `read ECONNRESET`, as Node's server reports it, and one that closes with `ECONNRESET` and `the client closed the connection during the TLS handshake` ([#1578](https://github.com/ai-ecoverse/slicc-kernel/issues/1578)). A loopback TLS client whose server resets before or during the handshake fails the same way, with `read ECONNRESET`, not `EPIPE` ([#1611](https://github.com/ai-ecoverse/slicc-kernel/issues/1611)). A handshake, server or loopback client, waits without holding the program's other calls, and an aborted `accept({ signal })` or `connect({ signal })` ends it. A signal delivered to the program doesn't interrupt a handshake, as with `SA_RESTART`.
541
+ - A client that sends a plain HTTP request instead of a ClientHello fails the handshake with `ERR_SSL_HTTP_REQUEST`, as in Node. A client that resets during the handshake fails it with `ECONNRESET` and `read ECONNRESET`, as Node's server reports it, and one that closes with `ECONNRESET` and `the client closed the connection during the TLS handshake` ([#1578](https://github.com/ai-ecoverse/slicc-kernel/issues/1578)). A loopback TLS client whose server resets before its ClientHello goes out fails with `ECONNRESET` and `connect ECONNRESET <host>:<port>` (only while nothing has been read from the server), and one reset on or after its ClientHello with `read ECONNRESET`, as Node 22 tells them apart, not `EPIPE` ([#1611](https://github.com/ai-ecoverse/slicc-kernel/issues/1611), [#1624](https://github.com/ai-ecoverse/slicc-kernel/issues/1624)). A handshake, server or loopback client, waits without holding the program's other calls, and an aborted `accept({ signal })` or `connect({ signal })` ends it. A signal delivered to the program doesn't interrupt a handshake, as with `SA_RESTART`.
542
542
  - **Choosing per connection** ([#1501](https://github.com/ai-ecoverse/slicc-kernel/issues/1501), [#1502](https://github.com/ai-ecoverse/slicc-kernel/issues/1502), tls-engine 4.2.0-9's `TLS_SERVER_SELECT`), for Node's `SNICallback`, `addContext` and `ALPNCallback`: `tls.select({ servername, protocols })` on `listen` or `secure` is called once the client's ClientHello is in, with the SNI (or `''`) and the protocols the client offers. It returns (or resolves with) `{ context, alpn }` or `{ refuse }`:
543
543
  - `context` is a certificate from `net.tlsContext({ cert, key, passphrase })` (or its `fd`); without it the listener's own `cert` serves, and with `select` that one is optional. `alpn` is one of `protocols`, or none; another is `EINVAL` and refuses the handshake. `select` and a fixed `alpn` list together are `EINVAL` (`ERR_TLS_ALPN_CALLBACK_WITH_PROTOCOLS`), as in Node.
544
544
  - `refuse` sends a fatal alert and ends the handshake: `'unrecognized_name'` (112), `'no_application_protocol'` (120), `'handshake_failure'` (40), `'access_denied'` (49) or `'internal_error'` (80), or the number. A `select` that throws refuses with 40, and one that doesn't answer within `handshakeTimeout` times the handshake out. On a listener the connection is dropped and the listener keeps accepting; `secure()` rejects with the error.
@@ -6458,6 +6458,10 @@ var KernelSocket = class _KernelSocket {
6458
6458
  if (bytes.length === 0 && this.reset) throw this.reset;
6459
6459
  return bytes;
6460
6460
  }
6461
+ connectReset() {
6462
+ const at = this.peer?.family === "inet" ? ` ${this.peer.host}:${this.peer.port}` : "";
6463
+ return `connect ECONNRESET${at}`;
6464
+ }
6461
6465
  drained(rx) {
6462
6466
  if (this.refused && rx.buffered === 0) throw this.refused;
6463
6467
  }
@@ -6641,6 +6645,7 @@ var KernelSocket = class _KernelSocket {
6641
6645
  signal.throwIfAborted();
6642
6646
  this.served = true;
6643
6647
  let handshaking = true;
6648
+ let heard = false;
6644
6649
  const view2 = {
6645
6650
  localAddr: "",
6646
6651
  remoteAddr: "",
@@ -6648,10 +6653,12 @@ var KernelSocket = class _KernelSocket {
6648
6653
  const bytes = await raw2.rx.read(SERVE_CHUNK, handshaking ? signal : void 0).catch(() => EMPTY);
6649
6654
  if (bytes.length === 0 && this.refused)
6650
6655
  throw new KernelError("ECONNRESET", "read ECONNRESET");
6656
+ heard ||= bytes.length > 0;
6651
6657
  return bytes.length > 0 ? bytes : null;
6652
6658
  },
6653
6659
  write: (bytes) => raw2.tx.write(bytes).catch((err) => {
6654
- throw this.refused ? new KernelError("ECONNRESET", "read ECONNRESET") : err;
6660
+ if (!this.refused) throw err;
6661
+ throw new KernelError("ECONNRESET", heard ? "read ECONNRESET" : this.connectReset());
6655
6662
  }),
6656
6663
  closeWrite: () => raw2.tx.closeWrite(),
6657
6664
  close: () => {
@@ -8437,7 +8444,7 @@ function satisfies(version, range2) {
8437
8444
  }
8438
8445
 
8439
8446
  // src/version.ts
8440
- var KERNEL_VERSION = true ? "1.164.0" : "0.0.0-dev";
8447
+ var KERNEL_VERSION = true ? "1.164.1" : "0.0.0-dev";
8441
8448
  var OS_RELEASE = "6.0.0-slicc";
8442
8449
  function procVersion() {
8443
8450
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC