@ai-ecoverse/slicc-kernel 1.148.0 → 1.149.0

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.
@@ -2964,7 +2964,7 @@ var KERNEL_VERSION, OS_RELEASE;
2964
2964
  var init_version = __esm({
2965
2965
  "src/version.ts"() {
2966
2966
  "use strict";
2967
- KERNEL_VERSION = true ? "1.148.0" : "0.0.0-dev";
2967
+ KERNEL_VERSION = true ? "1.149.0" : "0.0.0-dev";
2968
2968
  OS_RELEASE = "6.0.0-slicc";
2969
2969
  }
2970
2970
  });
@@ -7912,7 +7912,9 @@ var init_js_kernel = __esm({
7912
7912
  "fd-open-clipboard",
7913
7913
  "net-ws-ready",
7914
7914
  "sock-tls",
7915
- "sock-tls-upgrade"
7915
+ "sock-tls-upgrade",
7916
+ "sock-tls-serve",
7917
+ "sock-tls-listen"
7916
7918
  ]);
7917
7919
  JsKernel = class {
7918
7920
  header;
@@ -16598,22 +16600,44 @@ function caList(ca) {
16598
16600
  }
16599
16601
  return out;
16600
16602
  }
16601
- function keyText(key) {
16603
+ function keyText(key, what) {
16602
16604
  if (key instanceof Uint8Array) return toBase64(key);
16603
16605
  if (typeof key === "string") return toBase64(new TextEncoder().encode(key));
16604
- throw new JsCallError("EINVAL", "connect", "ERR_INVALID_ARG_TYPE: key must be a string or bytes");
16606
+ throw new JsCallError("EINVAL", what, "ERR_INVALID_ARG_TYPE: key must be a string or bytes");
16605
16607
  }
16606
- function clientCert(tls) {
16608
+ function serveRequest(tls) {
16609
+ const own = clientCert(tls, "listen").clientCert;
16610
+ if (!own)
16611
+ throw new JsCallError("EINVAL", "listen", "ERR_INVALID_ARG_VALUE: a server needs cert and key");
16612
+ return {
16613
+ cert: own,
16614
+ ...tls.ca !== void 0 ? { ca: caList(tls.ca) } : {},
16615
+ ...tls.requestCert ? { requestCert: true } : {},
16616
+ ...tls.rejectUnauthorized === false ? { rejectUnauthorized: false } : {},
16617
+ ...tls.alpn ? { alpn: [...tls.alpn] } : {},
16618
+ ...tls.handshakeTimeout !== void 0 ? { handshakeTimeout: tls.handshakeTimeout } : {}
16619
+ };
16620
+ }
16621
+ function servedOf(r) {
16622
+ const { authorizationError, ...rest2 } = r;
16623
+ return Object.freeze({
16624
+ ...rest2,
16625
+ path: "kernel",
16626
+ ...authorizationError ? { authorizationError } : {},
16627
+ peerCertificates: Object.freeze(r.peerCertificates.map(fromBase64))
16628
+ });
16629
+ }
16630
+ function clientCert(tls, what = "connect") {
16607
16631
  if (tls.pfx !== void 0) {
16608
- throw new JsCallError("ENOTSUP", "connect", "pfx is not supported: pass cert and key");
16632
+ throw new JsCallError("ENOTSUP", what, "pfx is not supported: pass cert and key");
16609
16633
  }
16610
16634
  if (tls.cert === void 0 && tls.key === void 0) return {};
16611
16635
  const chain3 = tls.cert === void 0 ? [] : caList(tls.cert);
16612
16636
  if (chain3.length === 0 || tls.key === void 0) {
16613
- throw new JsCallError("EINVAL", "connect", "ERR_INVALID_ARG_VALUE: cert and key go together");
16637
+ throw new JsCallError("EINVAL", what, "ERR_INVALID_ARG_VALUE: cert and key go together");
16614
16638
  }
16615
16639
  const passphrase = tls.passphrase === void 0 ? {} : { passphrase: String(tls.passphrase) };
16616
- return { clientCert: { chain: chain3, key: keyText(tls.key), ...passphrase } };
16640
+ return { clientCert: { chain: chain3, key: keyText(tls.key, what), ...passphrase } };
16617
16641
  }
16618
16642
  function tlsRequest(tls) {
16619
16643
  return {
@@ -16688,6 +16712,118 @@ function port(n) {
16688
16712
  if (!Number.isInteger(n) || n < 0 || n > 65535) throw new JsCallError("EINVAL", `port ${n}`);
16689
16713
  return n;
16690
16714
  }
16715
+ async function serveOn(kernel, conn, req, signal = NEVER) {
16716
+ const r = await secureCall(
16717
+ () => kernel.blocking({ op: "sock-tls-serve", fd: conn.fd, ...req }, signal),
16718
+ "accept"
16719
+ );
16720
+ const wire = r.ok && r.kind === "json" ? r.json : {};
16721
+ return Object.assign(Object.create(conn), { tls: servedOf(wire) });
16722
+ }
16723
+ function changeOf(waiters, signal) {
16724
+ return new Promise((resolve) => {
16725
+ const done = () => {
16726
+ waiters.delete(done);
16727
+ signal.removeEventListener("abort", done);
16728
+ resolve();
16729
+ };
16730
+ waiters.add(done);
16731
+ signal.addEventListener("abort", done, { once: true });
16732
+ });
16733
+ }
16734
+ function securedAccepts(plain2, serve, stop, cap) {
16735
+ const ready = [];
16736
+ const waiters = /* @__PURE__ */ new Set();
16737
+ let failure;
16738
+ let pumping = false;
16739
+ let inFlight = 0;
16740
+ const wake = () => {
16741
+ for (const w of [...waiters]) w();
16742
+ };
16743
+ const handshake = (conn) => {
16744
+ inFlight++;
16745
+ serve(conn, stop).then(
16746
+ (secured) => {
16747
+ if (stop.aborted) void secured.close();
16748
+ else ready.push(secured);
16749
+ },
16750
+ () => conn.close()
16751
+ ).finally(() => {
16752
+ inFlight--;
16753
+ wake();
16754
+ });
16755
+ };
16756
+ const pump2 = async () => {
16757
+ for (; ; ) {
16758
+ try {
16759
+ while (inFlight + ready.length >= cap) {
16760
+ stop.throwIfAborted();
16761
+ await changeOf(waiters, stop);
16762
+ }
16763
+ handshake(await plain2(stop));
16764
+ } catch (err) {
16765
+ failure = err;
16766
+ for (const left of ready.splice(0)) void left.close();
16767
+ wake();
16768
+ return;
16769
+ }
16770
+ }
16771
+ };
16772
+ return async (signal) => {
16773
+ if (!pumping) {
16774
+ pumping = true;
16775
+ void pump2();
16776
+ }
16777
+ for (; ; ) {
16778
+ if (stop.aborted) throw stop.reason;
16779
+ const next2 = ready.shift();
16780
+ if (next2) {
16781
+ wake();
16782
+ return next2;
16783
+ }
16784
+ if (failure !== void 0) throw failure;
16785
+ signal.throwIfAborted();
16786
+ await changeOf(waiters, signal);
16787
+ }
16788
+ };
16789
+ }
16790
+ function listenerOf(ops, fd, at, handshakes) {
16791
+ const { kernel, io, connection, serve } = ops;
16792
+ const stop = new AbortController();
16793
+ const acceptPlain = async (signal) => {
16794
+ for (; ; ) {
16795
+ signal.throwIfAborted();
16796
+ const r = await kernel.raw({ op: "sock-accept", fd, nonblock: true });
16797
+ if (r.ok) return connection((r.kind === "json" ? r.json : {}).fd);
16798
+ if (r.errno !== "EAGAIN") throw new JsCallError(r.errno, "accept");
16799
+ await kernel.blocking({ op: "fd-select", read: [fd], write: [], timeoutMs: -1 }, signal);
16800
+ }
16801
+ };
16802
+ const next2 = handshakes > 0 ? securedAccepts(acceptPlain, (c, s) => serve(c, { from: fd }, s), stop.signal, handshakes) : acceptPlain;
16803
+ const accept = (options = {}) => next2(AbortSignal.any([options.signal ?? NEVER, stop.signal]));
16804
+ return {
16805
+ fd,
16806
+ ...at,
16807
+ accept,
16808
+ async close() {
16809
+ stop.abort(new JsCallError("EBADF", "listener closed"));
16810
+ await io.close(fd);
16811
+ },
16812
+ async *[Symbol.asyncIterator]() {
16813
+ for (; ; ) {
16814
+ try {
16815
+ yield await accept();
16816
+ } catch (err) {
16817
+ if (stop.signal.aborted) return;
16818
+ throw err;
16819
+ }
16820
+ }
16821
+ }
16822
+ };
16823
+ }
16824
+ function capOf(options, tls) {
16825
+ return tls ? Math.max(1, Math.min(options.backlog ?? 128, HANDSHAKES_MAX)) : 0;
16826
+ }
16691
16827
  function netOps(kernel, io, sync) {
16692
16828
  const name2 = async (fd, peer) => addressOf(await kernel.json({ op: "sock-name", fd, peer }));
16693
16829
  const connection = async (fd) => {
@@ -16735,53 +16871,58 @@ function netOps(kernel, io, sync) {
16735
16871
  throw err;
16736
16872
  }
16737
16873
  };
16738
- const listener = (fd, at) => {
16739
- const stop = new AbortController();
16740
- const accept = async (options = {}) => {
16741
- const signal = AbortSignal.any([options.signal ?? NEVER, stop.signal]);
16742
- for (; ; ) {
16743
- signal.throwIfAborted();
16744
- const r = await kernel.raw({ op: "sock-accept", fd, nonblock: true });
16745
- if (r.ok) return connection((r.kind === "json" ? r.json : {}).fd);
16746
- if (r.errno !== "EAGAIN") throw new JsCallError(r.errno, "accept");
16747
- await kernel.blocking({ op: "fd-select", read: [fd], write: [], timeoutMs: -1 }, signal);
16748
- }
16749
- };
16750
- return {
16751
- fd,
16752
- ...at,
16753
- accept,
16754
- async close() {
16755
- stop.abort(new JsCallError("EBADF", "listener closed"));
16756
- await io.close(fd);
16757
- },
16758
- async *[Symbol.asyncIterator]() {
16759
- for (; ; ) {
16760
- try {
16761
- yield await accept();
16762
- } catch (err) {
16763
- if (stop.signal.aborted) return;
16764
- throw err;
16765
- }
16766
- }
16767
- }
16874
+ const serve = (conn, req, signal) => serveOn(kernel, conn, req, signal);
16875
+ const ops = { kernel, io, connection, serve };
16876
+ const listener = (fd, at, handshakes = 0) => listenerOf(ops, fd, at, handshakes);
16877
+ const connect = async (options) => {
16878
+ const signal = options.signal ?? NEVER;
16879
+ const host = options.host ?? "127.0.0.1";
16880
+ if (host.includes(":")) throw new JsCallError("EADDRNOTAVAIL", host);
16881
+ const addr = {
16882
+ family: "inet",
16883
+ host: await resolve(host, signal),
16884
+ port: port(options.port)
16768
16885
  };
16886
+ return opened2(async (fd) => {
16887
+ const r = await kernel.raw({ op: "sock-connect", fd, addr, nonblock: true });
16888
+ if (!r.ok && r.errno !== "EINPROGRESS") throw new JsCallError(r.errno, "connect");
16889
+ await kernel.blocking({ op: "fd-select", read: [], write: [fd], timeoutMs: -1 }, signal);
16890
+ const failed5 = await kernel.json({
16891
+ op: "sock-getopt",
16892
+ fd,
16893
+ level: SOL_SOCKET2,
16894
+ name: SO_ERROR2
16895
+ });
16896
+ if (failed5 !== 0) throw new JsCallError(errnoName(failed5), "connect");
16897
+ return connection(fd);
16898
+ });
16769
16899
  };
16770
16900
  const tlsConnect = async (options, tls) => {
16901
+ const host = options.host ?? "localhost";
16902
+ if (!options.socket && LOOPBACK3.test(host)) {
16903
+ const { tls: _, ...plain2 } = options;
16904
+ const socket = await connect({ ...plain2, host });
16905
+ return tlsConnect({ ...plain2, host, socket }, tls).catch(async (err) => {
16906
+ await socket.close();
16907
+ throw err;
16908
+ });
16909
+ }
16771
16910
  const common = tlsRequest(
16772
16911
  options.socket && !tls.servername && options.host ? { ...tls, servername: options.host } : tls
16773
16912
  );
16774
- const r = await secureCall(
16775
- () => kernel.json(
16776
- options.socket ? { op: "sock-tls-upgrade", fd: options.socket.fd, ...common } : {
16913
+ const r = await secureCall(async () => {
16914
+ if (!options.socket)
16915
+ return kernel.json({
16777
16916
  op: "sock-tls",
16778
- host: options.host ?? "localhost",
16917
+ host,
16779
16918
  port: port(options.port),
16780
16919
  ...common,
16781
16920
  ...tls.path ? { path: tls.path } : {}
16782
- }
16783
- )
16784
- );
16921
+ });
16922
+ const req = { op: "sock-tls-upgrade", fd: options.socket.fd, ...common };
16923
+ const done = await kernel.blocking(req, options.signal ?? NEVER);
16924
+ return done.ok && done.kind === "json" ? done.json : void 0;
16925
+ });
16785
16926
  const session = sessionOf(r);
16786
16927
  if (options.socket) return Object.assign(Object.create(options.socket), { tls: session });
16787
16928
  return Object.assign(await connection(r.fd), { tls: session });
@@ -16811,11 +16952,14 @@ function netOps(kernel, io, sync) {
16811
16952
  const listenSync = (options = {}) => {
16812
16953
  const lane = sync;
16813
16954
  const addr = inetAt(options);
16955
+ const tls = options.tls ? serveRequest(options.tls) : void 0;
16814
16956
  const fd = lane.json({ op: "sock-open", domain: "inet" });
16815
16957
  try {
16816
16958
  lane.call({ op: "sock-bind", fd, addr });
16817
16959
  lane.call({ op: "sock-listen", fd, backlog: options.backlog ?? 128 });
16818
- return listener(fd, addressOf(lane.json({ op: "sock-name", fd, peer: false })));
16960
+ if (tls) lane.call({ op: "sock-tls-listen", fd, ...tls });
16961
+ const at = addressOf(lane.json({ op: "sock-name", fd, peer: false }));
16962
+ return listener(fd, at, capOf(options, tls));
16819
16963
  } catch (err) {
16820
16964
  lane.raw({ op: "fd-close", fd });
16821
16965
  throw err;
@@ -16824,40 +16968,28 @@ function netOps(kernel, io, sync) {
16824
16968
  return {
16825
16969
  sync: { listen: listenSync },
16826
16970
  resolve: lookup2,
16827
- listen: (options = {}) => opened2(async (fd) => {
16828
- const addr = inetAt(options);
16829
- await kernel.call({ op: "sock-bind", fd, addr });
16830
- await kernel.call({ op: "sock-listen", fd, backlog: options.backlog ?? 128 });
16831
- return listener(fd, await name2(fd, false));
16832
- }),
16833
- connect: async (options) => {
16834
- const signal = options.signal ?? NEVER;
16835
- signal.throwIfAborted();
16836
- if (options.tls) return tlsConnect(options, options.tls);
16837
- const host = options.host ?? "127.0.0.1";
16838
- if (host.includes(":")) throw new JsCallError("EADDRNOTAVAIL", host);
16839
- const addr = {
16840
- family: "inet",
16841
- host: await resolve(host, signal),
16842
- port: port(options.port)
16843
- };
16971
+ listen: async (options = {}) => {
16972
+ const tls = options.tls ? serveRequest(options.tls) : void 0;
16844
16973
  return opened2(async (fd) => {
16845
- const r = await kernel.raw({ op: "sock-connect", fd, addr, nonblock: true });
16846
- if (!r.ok && r.errno !== "EINPROGRESS") throw new JsCallError(r.errno, "connect");
16847
- await kernel.blocking({ op: "fd-select", read: [], write: [fd], timeoutMs: -1 }, signal);
16848
- const failed5 = await kernel.json({
16849
- op: "sock-getopt",
16850
- fd,
16851
- level: SOL_SOCKET2,
16852
- name: SO_ERROR2
16853
- });
16854
- if (failed5 !== 0) throw new JsCallError(errnoName(failed5), "connect");
16855
- return connection(fd);
16974
+ const addr = inetAt(options);
16975
+ await kernel.call({ op: "sock-bind", fd, addr });
16976
+ await kernel.call({ op: "sock-listen", fd, backlog: options.backlog ?? 128 });
16977
+ if (tls)
16978
+ await secureCall(() => kernel.call({ op: "sock-tls-listen", fd, ...tls }), "listen");
16979
+ return listener(fd, await name2(fd, false), capOf(options, tls));
16856
16980
  });
16981
+ },
16982
+ secure: async (conn, tls) => {
16983
+ if (tls.server !== true) return tlsConnect({ socket: conn }, tls);
16984
+ return serve(conn, serveRequest(tls));
16985
+ },
16986
+ connect: (options) => {
16987
+ (options.signal ?? NEVER).throwIfAborted();
16988
+ return options.tls ? tlsConnect(options, options.tls) : connect(options);
16857
16989
  }
16858
16990
  };
16859
16991
  }
16860
- var PEM, TLS_CODE, ALERT, SHUT_RD, SHUT_WR, IPV4, NEVER, SOL_SOCKET2, SO_ERROR2;
16992
+ var PEM, TLS_CODE, ALERT, SHUT_RD, SHUT_WR, LOOPBACK3, IPV4, NEVER, SOL_SOCKET2, SO_ERROR2, HANDSHAKES_MAX;
16861
16993
  var init_js_net = __esm({
16862
16994
  "src/process/js/js-net.ts"() {
16863
16995
  "use strict";
@@ -16868,10 +17000,12 @@ var init_js_net = __esm({
16868
17000
  ALERT = / \(alert (\d+)\)$/;
16869
17001
  SHUT_RD = 0;
16870
17002
  SHUT_WR = 1;
17003
+ LOOPBACK3 = /^(localhost|127\.\d{1,3}\.\d{1,3}\.\d{1,3})$/;
16871
17004
  IPV4 = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
16872
17005
  NEVER = new AbortController().signal;
16873
17006
  SOL_SOCKET2 = 1;
16874
17007
  SO_ERROR2 = 4;
17008
+ HANDSHAKES_MAX = 64;
16875
17009
  }
16876
17010
  });
16877
17011