@ai-ecoverse/slicc-kernel 1.124.12 → 1.125.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.
- package/README.md +46 -11
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +548 -94
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +4496 -4350
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +553 -99
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +7137 -6991
- package/dist/process-worker.js.map +4 -4
- package/dist/types/fs/unlinked.d.ts +1 -0
- package/dist/types/fs/watch.d.ts +19 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/kernel/fd-table.d.ts +1 -0
- package/dist/types/kernel/host.d.ts +1 -0
- package/dist/types/kernel/net/tls-ciphers.d.ts +6 -0
- package/dist/types/kernel/net/tls-client.d.ts +13 -1
- package/dist/types/kernel/net/tls-engine.d.ts +10 -0
- package/dist/types/kernel/net/tls-uplink.d.ts +14 -1
- package/dist/types/kernel/net/uplink-socket.d.ts +1 -1
- package/dist/types/kernel/process.d.ts +4 -1
- package/dist/types/kernel/select.d.ts +1 -0
- package/dist/types/kernel/socket-syscalls.d.ts +7 -0
- package/dist/types/kernel/vfs-file.d.ts +2 -0
- package/dist/types/kernel/watch-ops.d.ts +30 -0
- package/dist/types/launcher.d.ts +1 -0
- package/dist/types/process/js/js-context.d.ts +2 -0
- package/dist/types/process/js/js-dev.d.ts +1 -0
- package/dist/types/process/js/js-net.d.ts +16 -0
- package/dist/types/process/js/js-sync.d.ts +5 -1
- package/dist/types/process/js/js-watch.d.ts +17 -0
- package/dist/types/process/process-fds.d.ts +1 -1
- package/dist/types/process/wasi/wasi-host.d.ts +1 -0
- package/package.json +4 -4
package/dist/node.js
CHANGED
|
@@ -930,7 +930,12 @@ function openPipe(capacity) {
|
|
|
930
930
|
}
|
|
931
931
|
},
|
|
932
932
|
close: () => pipe.closeRead(),
|
|
933
|
-
poll: () => ({
|
|
933
|
+
poll: () => ({
|
|
934
|
+
readable: pipe.readReady,
|
|
935
|
+
writable: false,
|
|
936
|
+
hangup: pipe.writersGone,
|
|
937
|
+
nread: pipe.buffered
|
|
938
|
+
}),
|
|
934
939
|
changed: (signal) => pipe.changed(signal),
|
|
935
940
|
identity: pipe
|
|
936
941
|
}),
|
|
@@ -1557,8 +1562,8 @@ function uplinkLink(conn, onReset) {
|
|
|
1557
1562
|
open = false;
|
|
1558
1563
|
conn.close();
|
|
1559
1564
|
};
|
|
1560
|
-
void inbound(conn, rx).catch(() => {
|
|
1561
|
-
onReset();
|
|
1565
|
+
void inbound(conn, rx).catch((err) => {
|
|
1566
|
+
onReset(err);
|
|
1562
1567
|
close();
|
|
1563
1568
|
tx.closeRead();
|
|
1564
1569
|
}).finally(() => rx.closeWrite());
|
|
@@ -1649,7 +1654,7 @@ var KernelSocket = class _KernelSocket {
|
|
|
1649
1654
|
state = "open";
|
|
1650
1655
|
dialing;
|
|
1651
1656
|
failed;
|
|
1652
|
-
reset
|
|
1657
|
+
reset;
|
|
1653
1658
|
local;
|
|
1654
1659
|
peer;
|
|
1655
1660
|
peerCred;
|
|
@@ -1688,19 +1693,20 @@ var KernelSocket = class _KernelSocket {
|
|
|
1688
1693
|
const { rx } = this.connection();
|
|
1689
1694
|
if (this.readShut || max <= 0) return new Uint8Array(0);
|
|
1690
1695
|
const bytes = await pipeCall(() => rx.read(max, signal));
|
|
1691
|
-
if (bytes.length === 0 && this.reset) throw
|
|
1696
|
+
if (bytes.length === 0 && this.reset) throw this.reset;
|
|
1692
1697
|
return bytes;
|
|
1693
1698
|
}
|
|
1694
1699
|
async peek(max, signal) {
|
|
1695
1700
|
const { rx } = this.connection();
|
|
1696
1701
|
if (this.readShut || max <= 0) return new Uint8Array(0);
|
|
1697
1702
|
const bytes = await pipeCall(() => rx.peek(max, signal));
|
|
1698
|
-
if (bytes.length === 0 && this.reset) throw
|
|
1703
|
+
if (bytes.length === 0 && this.reset) throw this.reset;
|
|
1699
1704
|
return bytes;
|
|
1700
1705
|
}
|
|
1701
1706
|
async write(bytes, signal) {
|
|
1702
1707
|
const { tx } = this.connection();
|
|
1703
1708
|
if (this.writeShut) throw new KernelError("EPIPE");
|
|
1709
|
+
if (this.reset?.code === "EPROTO") throw this.reset;
|
|
1704
1710
|
return pipeCall(() => tx.write(bytes, signal));
|
|
1705
1711
|
}
|
|
1706
1712
|
poll() {
|
|
@@ -1717,7 +1723,8 @@ var KernelSocket = class _KernelSocket {
|
|
|
1717
1723
|
readable: this.readShut || rx.readReady,
|
|
1718
1724
|
writable: this.writeShut || tx.writeReady,
|
|
1719
1725
|
hangup: rx.writersGone && tx.readersGone,
|
|
1720
|
-
rdhup: rx.writersGone
|
|
1726
|
+
rdhup: rx.writersGone,
|
|
1727
|
+
nread: this.readShut ? 0 : rx.buffered
|
|
1721
1728
|
};
|
|
1722
1729
|
}
|
|
1723
1730
|
changed(signal) {
|
|
@@ -1777,8 +1784,8 @@ var KernelSocket = class _KernelSocket {
|
|
|
1777
1784
|
if (this.state !== "open") throw new KernelError("EINVAL");
|
|
1778
1785
|
if (addr.family !== this.domain) throw new KernelError("EAFNOSUPPORT");
|
|
1779
1786
|
this.failed = void 0;
|
|
1780
|
-
const
|
|
1781
|
-
if (
|
|
1787
|
+
const route2 = viaUplink && addr.family === "inet" ? this.net.uplinkFor(addr.host) : void 0;
|
|
1788
|
+
if (route2) return this.dial(addr, route2);
|
|
1782
1789
|
const target = this.net.target(addr, name2);
|
|
1783
1790
|
if (!this.local) {
|
|
1784
1791
|
if (addr.family === "inet") {
|
|
@@ -1834,9 +1841,9 @@ var KernelSocket = class _KernelSocket {
|
|
|
1834
1841
|
}
|
|
1835
1842
|
}
|
|
1836
1843
|
switch;
|
|
1837
|
-
connectSecure(addr,
|
|
1844
|
+
connectSecure(addr, route2, secure2) {
|
|
1838
1845
|
if (this.state !== "open") throw new KernelError("EISCONN");
|
|
1839
|
-
return this.dial(addr,
|
|
1846
|
+
return this.dial(addr, route2, secure2);
|
|
1840
1847
|
}
|
|
1841
1848
|
upgradeSecure(make) {
|
|
1842
1849
|
if (this.state !== "connected") throw new KernelError("ENOTCONN");
|
|
@@ -1844,7 +1851,7 @@ var KernelSocket = class _KernelSocket {
|
|
|
1844
1851
|
if (this.switch.upgraded || this.writeShut || this.readShut) throw new KernelError("EINVAL");
|
|
1845
1852
|
return this.switch.upgrade(make);
|
|
1846
1853
|
}
|
|
1847
|
-
dial(addr,
|
|
1854
|
+
dial(addr, route2, secure2) {
|
|
1848
1855
|
this.state = "connecting";
|
|
1849
1856
|
const abort = new AbortController();
|
|
1850
1857
|
this.dialing = abort;
|
|
@@ -1852,13 +1859,13 @@ var KernelSocket = class _KernelSocket {
|
|
|
1852
1859
|
const timer = setTimeout(() => {
|
|
1853
1860
|
timedOut = true;
|
|
1854
1861
|
abort.abort(new KernelError("ETIMEDOUT"));
|
|
1855
|
-
},
|
|
1862
|
+
}, route2.timeoutMs ?? DIAL_TIMEOUT_MS);
|
|
1856
1863
|
const abandoned = new Promise((_, reject) => {
|
|
1857
1864
|
abort.signal.addEventListener("abort", () => reject(abort.signal.reason), { once: true });
|
|
1858
1865
|
});
|
|
1859
1866
|
const { host, port } = addr;
|
|
1860
1867
|
const dialled = new Promise(
|
|
1861
|
-
(resolve2) => resolve2(
|
|
1868
|
+
(resolve2) => resolve2(route2.uplink.dial({ network: "tcp", host, port, signal: abort.signal }))
|
|
1862
1869
|
);
|
|
1863
1870
|
dialled.then(
|
|
1864
1871
|
(conn) => abort.signal.aborted && conn.close(),
|
|
@@ -1885,8 +1892,8 @@ var KernelSocket = class _KernelSocket {
|
|
|
1885
1892
|
this.dialing = void 0;
|
|
1886
1893
|
this.switch = conn;
|
|
1887
1894
|
this.attach(
|
|
1888
|
-
uplinkLink(conn, () => {
|
|
1889
|
-
this.reset =
|
|
1895
|
+
uplinkLink(conn, (err) => {
|
|
1896
|
+
this.reset = err instanceof KernelError && err.code === "EPROTO" ? err : new KernelError("ECONNRESET");
|
|
1890
1897
|
this.changes.wake();
|
|
1891
1898
|
})
|
|
1892
1899
|
);
|
|
@@ -2007,14 +2014,14 @@ var LoopbackNet = class {
|
|
|
2007
2014
|
if (!this.origins) throw new KernelError("ENETUNREACH");
|
|
2008
2015
|
void this.origins(conn, origin).catch(() => conn.close());
|
|
2009
2016
|
}
|
|
2010
|
-
useUplink(
|
|
2011
|
-
this.route =
|
|
2017
|
+
useUplink(route2) {
|
|
2018
|
+
this.route = route2;
|
|
2012
2019
|
}
|
|
2013
2020
|
tlsClient;
|
|
2014
2021
|
uplinkFor(host) {
|
|
2015
|
-
const
|
|
2016
|
-
if (!
|
|
2017
|
-
return this.destination(host) === "uplink" ?
|
|
2022
|
+
const route2 = this.route;
|
|
2023
|
+
if (!route2) return void 0;
|
|
2024
|
+
return this.destination(host) === "uplink" ? route2 : void 0;
|
|
2018
2025
|
}
|
|
2019
2026
|
destination(host) {
|
|
2020
2027
|
return (this.route?.routes ?? LOCAL_ONLY).classify(host);
|
|
@@ -5993,16 +6000,24 @@ var UnlinkedKeeper = class {
|
|
|
5993
6000
|
gated();
|
|
5994
6001
|
const held = /* @__PURE__ */ new Map();
|
|
5995
6002
|
const hidden = /* @__PURE__ */ new Map();
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
const
|
|
6004
|
-
|
|
6003
|
+
const moved2 = [];
|
|
6004
|
+
try {
|
|
6005
|
+
for (; ; ) {
|
|
6006
|
+
await take();
|
|
6007
|
+
const now = this.heldWithin(target);
|
|
6008
|
+
const next3 = paths.filter((path) => now.has(path) && !held.has(path));
|
|
6009
|
+
if (next3.length === 0) break;
|
|
6010
|
+
for (const path of next3) {
|
|
6011
|
+
const holders = now.get(path);
|
|
6012
|
+
held.set(path, holders);
|
|
6013
|
+
for (const holder of holders) moved2.push(holder.moving?.(path) ?? (() => void 0));
|
|
6014
|
+
const at = await this.hide(path);
|
|
6015
|
+
if (at !== void 0) hidden.set(path, at);
|
|
6016
|
+
}
|
|
6005
6017
|
}
|
|
6018
|
+
} catch (err) {
|
|
6019
|
+
for (const settle of moved2) settle();
|
|
6020
|
+
throw err;
|
|
6006
6021
|
}
|
|
6007
6022
|
sealed();
|
|
6008
6023
|
const done4 = () => {
|
|
@@ -6015,6 +6030,7 @@ var UnlinkedKeeper = class {
|
|
|
6015
6030
|
files.set(path, file);
|
|
6016
6031
|
for (const holder of holders) holder.keep(path, file);
|
|
6017
6032
|
}
|
|
6033
|
+
for (const settle of moved2) settle();
|
|
6018
6034
|
return {
|
|
6019
6035
|
moved: new Set(hidden.keys()),
|
|
6020
6036
|
commit: () => {
|
|
@@ -7070,7 +7086,7 @@ function satisfies(version, range2) {
|
|
|
7070
7086
|
}
|
|
7071
7087
|
|
|
7072
7088
|
// src/version.ts
|
|
7073
|
-
var KERNEL_VERSION = true ? "1.
|
|
7089
|
+
var KERNEL_VERSION = true ? "1.125.0" : "0.0.0-dev";
|
|
7074
7090
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7075
7091
|
function procVersion() {
|
|
7076
7092
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -9504,6 +9520,8 @@ async function physicalPathAsync(fs, path) {
|
|
|
9504
9520
|
}
|
|
9505
9521
|
|
|
9506
9522
|
// src/fs/watch.ts
|
|
9523
|
+
var WATCH_NOTES_LIMIT = 1e3;
|
|
9524
|
+
var baseOf2 = (path) => path.slice(path.lastIndexOf("/") + 1);
|
|
9507
9525
|
var WATCH_BATCH_LIMIT = 1e3;
|
|
9508
9526
|
var under3 = (path, dir) => dir === "/" || path.startsWith(`${dir}/`);
|
|
9509
9527
|
var parentOf6 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
|
|
@@ -9513,8 +9531,39 @@ function touches(watcher, changed) {
|
|
|
9513
9531
|
);
|
|
9514
9532
|
}
|
|
9515
9533
|
var REALS_KEPT = 4096;
|
|
9534
|
+
function noted(watch, note) {
|
|
9535
|
+
if (watch.ended) return;
|
|
9536
|
+
if ("ended" in note) {
|
|
9537
|
+
watch.notes.push(note);
|
|
9538
|
+
watch.ended = true;
|
|
9539
|
+
watch.wake?.();
|
|
9540
|
+
return;
|
|
9541
|
+
}
|
|
9542
|
+
if (watch.overflowed) return;
|
|
9543
|
+
if (watch.notes.length >= WATCH_NOTES_LIMIT) {
|
|
9544
|
+
watch.overflowed = true;
|
|
9545
|
+
watch.notes.push({ overflow: true });
|
|
9546
|
+
} else watch.notes.push(note);
|
|
9547
|
+
watch.wake?.();
|
|
9548
|
+
}
|
|
9549
|
+
function route(watch, type, path) {
|
|
9550
|
+
for (const root of watch.roots) if (routed(watch, root, type, path)) return;
|
|
9551
|
+
}
|
|
9552
|
+
function routed(watch, root, type, path) {
|
|
9553
|
+
if (path === root || type === "rename" && root !== "/" && under3(root, path)) {
|
|
9554
|
+
noted(watch, { type, filename: baseOf2(root) });
|
|
9555
|
+
if (type === "rename") noted(watch, { ended: true });
|
|
9556
|
+
return true;
|
|
9557
|
+
}
|
|
9558
|
+
if (parentOf6(path) === root) noted(watch, { type, filename: baseOf2(path) });
|
|
9559
|
+
else if (watch.recursive && under3(path, root)) {
|
|
9560
|
+
noted(watch, { type, filename: path.slice(root === "/" ? 1 : root.length + 1) });
|
|
9561
|
+
} else return false;
|
|
9562
|
+
return true;
|
|
9563
|
+
}
|
|
9516
9564
|
var FsWatchers = class {
|
|
9517
9565
|
watchers = /* @__PURE__ */ new Set();
|
|
9566
|
+
typed = /* @__PURE__ */ new Set();
|
|
9518
9567
|
taps = [];
|
|
9519
9568
|
reals = /* @__PURE__ */ new Map();
|
|
9520
9569
|
reshapes = [];
|
|
@@ -9541,7 +9590,65 @@ var FsWatchers = class {
|
|
|
9541
9590
|
this.watchers.delete(watcher);
|
|
9542
9591
|
};
|
|
9543
9592
|
}
|
|
9593
|
+
typedWatch(root, recursive, alias) {
|
|
9594
|
+
const main = normalizePath(root);
|
|
9595
|
+
const other = alias === void 0 ? main : normalizePath(alias);
|
|
9596
|
+
const watch = {
|
|
9597
|
+
roots: other === main ? [main] : [main, other],
|
|
9598
|
+
recursive,
|
|
9599
|
+
notes: [],
|
|
9600
|
+
overflowed: false,
|
|
9601
|
+
ended: false,
|
|
9602
|
+
wake: void 0
|
|
9603
|
+
};
|
|
9604
|
+
this.typed.add(watch);
|
|
9605
|
+
const close = () => {
|
|
9606
|
+
this.typed.delete(watch);
|
|
9607
|
+
watch.ended = true;
|
|
9608
|
+
watch.wake?.();
|
|
9609
|
+
};
|
|
9610
|
+
return {
|
|
9611
|
+
close,
|
|
9612
|
+
next: async (signal) => {
|
|
9613
|
+
while (watch.notes.length === 0 && !watch.ended && !signal.aborted) {
|
|
9614
|
+
await new Promise((resolve2) => {
|
|
9615
|
+
const done4 = () => {
|
|
9616
|
+
watch.wake = void 0;
|
|
9617
|
+
signal.removeEventListener("abort", done4);
|
|
9618
|
+
resolve2();
|
|
9619
|
+
};
|
|
9620
|
+
watch.wake = done4;
|
|
9621
|
+
signal.addEventListener("abort", done4, { once: true });
|
|
9622
|
+
});
|
|
9623
|
+
}
|
|
9624
|
+
const notes = watch.notes.splice(0);
|
|
9625
|
+
watch.overflowed = false;
|
|
9626
|
+
if (watch.ended) this.typed.delete(watch);
|
|
9627
|
+
return notes.length === 0 && watch.ended ? [{ ended: true }] : notes;
|
|
9628
|
+
}
|
|
9629
|
+
};
|
|
9630
|
+
}
|
|
9631
|
+
covers(path) {
|
|
9632
|
+
for (const watch of this.typed) {
|
|
9633
|
+
for (const root of watch.roots) {
|
|
9634
|
+
if (path === root || parentOf6(path) === root || watch.recursive && under3(path, root))
|
|
9635
|
+
return true;
|
|
9636
|
+
}
|
|
9637
|
+
}
|
|
9638
|
+
return false;
|
|
9639
|
+
}
|
|
9640
|
+
emit(type, paths) {
|
|
9641
|
+
if (this.typed.size === 0) return;
|
|
9642
|
+
for (const path of paths) {
|
|
9643
|
+
const at = normalizePath(path);
|
|
9644
|
+
for (const watch of [...this.typed]) route(watch, type, at);
|
|
9645
|
+
}
|
|
9646
|
+
}
|
|
9544
9647
|
changed(...paths) {
|
|
9648
|
+
this.report(paths);
|
|
9649
|
+
this.emit("change", paths);
|
|
9650
|
+
}
|
|
9651
|
+
report(paths) {
|
|
9545
9652
|
for (const tap of this.taps) tap(paths);
|
|
9546
9653
|
for (const watcher of this.watchers) {
|
|
9547
9654
|
for (const path of paths) {
|
|
@@ -9561,11 +9668,15 @@ var FsWatchers = class {
|
|
|
9561
9668
|
watcher.notify(paths.length > WATCH_BATCH_LIMIT ? { overflow: true } : { paths });
|
|
9562
9669
|
}
|
|
9563
9670
|
wrap(fs) {
|
|
9564
|
-
const after = (run2, changed) => async (...args) => {
|
|
9671
|
+
const after = (run2, changed, type) => async (...args) => {
|
|
9672
|
+
let done4 = false;
|
|
9565
9673
|
try {
|
|
9566
9674
|
await run2(...args);
|
|
9675
|
+
done4 = true;
|
|
9567
9676
|
} finally {
|
|
9568
|
-
|
|
9677
|
+
const paths = changed(...args);
|
|
9678
|
+
this.report(paths);
|
|
9679
|
+
if (done4) this.emit(type, paths);
|
|
9569
9680
|
}
|
|
9570
9681
|
};
|
|
9571
9682
|
const reals = this.reals;
|
|
@@ -9584,15 +9695,21 @@ var FsWatchers = class {
|
|
|
9584
9695
|
reals.set(at, real);
|
|
9585
9696
|
return real;
|
|
9586
9697
|
};
|
|
9587
|
-
const content = (run2) => async (...args) => {
|
|
9698
|
+
const content = (run2, types) => async (...args) => {
|
|
9699
|
+
const at = normalizePath(args[0]);
|
|
9700
|
+
const fresh2 = this.covers(at) && !await fs.exists(at).catch(() => true);
|
|
9701
|
+
let done4 = false;
|
|
9588
9702
|
try {
|
|
9589
9703
|
await run2(...args);
|
|
9704
|
+
done4 = true;
|
|
9590
9705
|
} finally {
|
|
9591
|
-
const at = normalizePath(args[0]);
|
|
9592
9706
|
const real = await realOf(at);
|
|
9593
|
-
|
|
9707
|
+
const paths = real === at ? [at] : [at, real];
|
|
9708
|
+
this.report(paths);
|
|
9709
|
+
if (done4) for (const type of types(fresh2)) this.emit(type, paths);
|
|
9594
9710
|
}
|
|
9595
9711
|
};
|
|
9712
|
+
const written2 = (fresh2) => fresh2 ? ["rename", "change"] : ["change"];
|
|
9596
9713
|
const reshaping = (run2) => async (...args) => {
|
|
9597
9714
|
this.reshaped();
|
|
9598
9715
|
try {
|
|
@@ -9602,8 +9719,8 @@ var FsWatchers = class {
|
|
|
9602
9719
|
}
|
|
9603
9720
|
};
|
|
9604
9721
|
const overrides = {
|
|
9605
|
-
writeFile: content(fs.writeFile.bind(fs)),
|
|
9606
|
-
...fs.createExclusive ? { createExclusive: content(fs.createExclusive.bind(fs)) } : {},
|
|
9722
|
+
writeFile: content(fs.writeFile.bind(fs), written2),
|
|
9723
|
+
...fs.createExclusive ? { createExclusive: content(fs.createExclusive.bind(fs), () => ["rename"]) } : {},
|
|
9607
9724
|
mkdir: async (path, options) => {
|
|
9608
9725
|
const created3 = [];
|
|
9609
9726
|
if (options?.recursive) {
|
|
@@ -9613,33 +9730,39 @@ var FsWatchers = class {
|
|
|
9613
9730
|
if (created3.length > 0 || !await fs.exists(ancestor)) created3.push(ancestor);
|
|
9614
9731
|
}
|
|
9615
9732
|
}
|
|
9733
|
+
const fresh2 = !options?.recursive || !(this.covers(path) && await fs.exists(path));
|
|
9734
|
+
let done4 = false;
|
|
9616
9735
|
try {
|
|
9617
9736
|
await fs.mkdir(path, options);
|
|
9737
|
+
done4 = true;
|
|
9618
9738
|
} finally {
|
|
9619
|
-
this.
|
|
9739
|
+
this.report([...created3, path]);
|
|
9740
|
+
if (done4) this.emit("rename", fresh2 ? [...created3, path] : created3);
|
|
9620
9741
|
}
|
|
9621
9742
|
},
|
|
9622
|
-
rm: reshaping(after(fs.rm.bind(fs), (path) => [path])),
|
|
9623
|
-
rename: reshaping(after(fs.rename.bind(fs), (from, to) => [from, to])),
|
|
9743
|
+
rm: reshaping(after(fs.rm.bind(fs), (path) => [path], "rename")),
|
|
9744
|
+
rename: reshaping(after(fs.rename.bind(fs), (from, to) => [from, to], "rename")),
|
|
9624
9745
|
link: reshaping(
|
|
9625
9746
|
after(
|
|
9626
9747
|
(from, to, follow2) => fs.link(from, to, follow2),
|
|
9627
|
-
(_from, to) => [to]
|
|
9748
|
+
(_from, to) => [to],
|
|
9749
|
+
"rename"
|
|
9628
9750
|
)
|
|
9629
9751
|
),
|
|
9630
|
-
symlink: reshaping(after(fs.symlink.bind(fs), (_target, path) => [path])),
|
|
9631
|
-
chmod: after(fs.chmod.bind(fs), (path) => [path]),
|
|
9632
|
-
...fs.chown ? { chown: after(fs.chown.bind(fs), (path) => [path]) } : {},
|
|
9633
|
-
utimes: after(fs.utimes.bind(fs), (path) => [path]),
|
|
9752
|
+
symlink: reshaping(after(fs.symlink.bind(fs), (_target, path) => [path], "rename")),
|
|
9753
|
+
chmod: after(fs.chmod.bind(fs), (path) => [path], "change"),
|
|
9754
|
+
...fs.chown ? { chown: after(fs.chown.bind(fs), (path) => [path], "change") } : {},
|
|
9755
|
+
utimes: after(fs.utimes.bind(fs), (path) => [path], "change"),
|
|
9634
9756
|
lutimes: after(
|
|
9635
9757
|
(path, atime, mtime) => lutimesOf(fs, path, atime, mtime),
|
|
9636
|
-
(path) => [path]
|
|
9758
|
+
(path) => [path],
|
|
9759
|
+
"change"
|
|
9637
9760
|
)
|
|
9638
9761
|
};
|
|
9639
9762
|
const ranged2 = rangedOps(fs);
|
|
9640
9763
|
if (ranged2) {
|
|
9641
|
-
overrides.pwrite = content(ranged2.pwrite);
|
|
9642
|
-
overrides.truncate = content(ranged2.truncate);
|
|
9764
|
+
overrides.pwrite = content(ranged2.pwrite, () => ["change"]);
|
|
9765
|
+
overrides.truncate = content(ranged2.truncate, () => ["change"]);
|
|
9643
9766
|
}
|
|
9644
9767
|
return new Proxy(fs, {
|
|
9645
9768
|
get(target, key, receiver) {
|
|
@@ -10247,7 +10370,8 @@ var FifoTable = class {
|
|
|
10247
10370
|
poll: () => ({
|
|
10248
10371
|
readable: reads && pipe.readReady,
|
|
10249
10372
|
writable: writes && pipe.writeReady,
|
|
10250
|
-
hangup: reads ? pipe.writersGone : pipe.readersGone
|
|
10373
|
+
hangup: reads ? pipe.writersGone : pipe.readersGone,
|
|
10374
|
+
...reads ? { nread: pipe.buffered } : {}
|
|
10251
10375
|
}),
|
|
10252
10376
|
changed: (signal) => pipe.changed(signal)
|
|
10253
10377
|
});
|
|
@@ -10646,8 +10770,8 @@ var MountTable = class {
|
|
|
10646
10770
|
...error ? { error } : {}
|
|
10647
10771
|
})
|
|
10648
10772
|
);
|
|
10649
|
-
const
|
|
10650
|
-
return [...mounted, ...
|
|
10773
|
+
const noted2 = [...this.notes.values()].filter((note) => !this.mounts.has(note.target));
|
|
10774
|
+
return [...mounted, ...noted2.map((note) => ({ ...note, options: { ...note.options } }))];
|
|
10651
10775
|
}
|
|
10652
10776
|
listed() {
|
|
10653
10777
|
return this.list().filter((entry) => !this.system.has(entry.target));
|
|
@@ -14824,6 +14948,8 @@ function realmCa(owner, store) {
|
|
|
14824
14948
|
|
|
14825
14949
|
// src/kernel/net/tls-engine.ts
|
|
14826
14950
|
var TLS_CLIENT_INSECURE_SKIP_VERIFY = 1;
|
|
14951
|
+
var TLS_CLIENT_NO_SNI = 2;
|
|
14952
|
+
var TLS_CLIENT_VERIFY_CHAIN_ONLY = 4;
|
|
14827
14953
|
var SCRATCH = 64 * 1024;
|
|
14828
14954
|
var EOF = -1;
|
|
14829
14955
|
var TlsError = class extends Error {
|
|
@@ -14880,10 +15006,22 @@ var TlsEngine = class {
|
|
|
14880
15006
|
this.m._free(ptr);
|
|
14881
15007
|
}
|
|
14882
15008
|
}
|
|
15009
|
+
withSecret(bytes, fn) {
|
|
15010
|
+
const ptr = this.put(bytes);
|
|
15011
|
+
try {
|
|
15012
|
+
return fn(ptr);
|
|
15013
|
+
} finally {
|
|
15014
|
+
this.m.HEAPU8.fill(0, ptr, ptr + bytes.length + 1);
|
|
15015
|
+
this.m._free(ptr);
|
|
15016
|
+
}
|
|
15017
|
+
}
|
|
14883
15018
|
intoScratch(fn) {
|
|
14884
15019
|
const n = fn(this.scratch, SCRATCH);
|
|
14885
15020
|
return n > 0 ? this.taken(n) : n;
|
|
14886
15021
|
}
|
|
15022
|
+
get sessionControls() {
|
|
15023
|
+
return typeof this.m._tls_client_cert === "function";
|
|
15024
|
+
}
|
|
14887
15025
|
get client() {
|
|
14888
15026
|
return typeof this.m._tls_client_new === "function" ? this.m : void 0;
|
|
14889
15027
|
}
|
|
@@ -15036,6 +15174,27 @@ var TlsSession = class {
|
|
|
15036
15174
|
const out = this.engine.intoScratch((p, max) => this.c._tls_alpn(this.ptr, p, max));
|
|
15037
15175
|
return out instanceof Uint8Array ? new TextDecoder().decode(out) : void 0;
|
|
15038
15176
|
}
|
|
15177
|
+
ownCert(chain2, key, pass2) {
|
|
15178
|
+
const set3 = this.m._tls_client_cert;
|
|
15179
|
+
const keyLen = key[0] === 45 ? key.length + 1 : key.length;
|
|
15180
|
+
const ret = this.engine.withBytes(
|
|
15181
|
+
chain2,
|
|
15182
|
+
(c) => this.engine.withSecret(
|
|
15183
|
+
key,
|
|
15184
|
+
(k) => this.engine.withSecret(
|
|
15185
|
+
pass2,
|
|
15186
|
+
(p) => set3(this.ptr, c, chain2.length, k, keyLen, pass2.length > 0 ? p : 0, pass2.length)
|
|
15187
|
+
)
|
|
15188
|
+
)
|
|
15189
|
+
);
|
|
15190
|
+
if (ret !== 0) throw this.engine.error(ret, "client certificate");
|
|
15191
|
+
}
|
|
15192
|
+
get ciphersuite() {
|
|
15193
|
+
return this.m._tls_ciphersuite(this.ptr);
|
|
15194
|
+
}
|
|
15195
|
+
get nameMismatch() {
|
|
15196
|
+
return this.m._tls_name_mismatch(this.ptr) === 1;
|
|
15197
|
+
}
|
|
15039
15198
|
peerChain() {
|
|
15040
15199
|
const chain2 = [];
|
|
15041
15200
|
const count2 = this.c._tls_peer_count(this.ptr);
|
|
@@ -15923,7 +16082,8 @@ var KernelTty = class {
|
|
|
15923
16082
|
poll: () => ({
|
|
15924
16083
|
readable: this.readable.length > 0 || this.hungUp,
|
|
15925
16084
|
writable: true,
|
|
15926
|
-
hangup: this.hungUp
|
|
16085
|
+
hangup: this.hungUp,
|
|
16086
|
+
nread: this.readable.reduce((n, chunk2) => n + (chunk2?.length ?? 0), 0)
|
|
15927
16087
|
}),
|
|
15928
16088
|
changed: (signal) => this.changed(signal),
|
|
15929
16089
|
close: () => {
|
|
@@ -16119,7 +16279,8 @@ var PtyPair = class {
|
|
|
16119
16279
|
poll: () => ({
|
|
16120
16280
|
readable: this.queue.length > 0 || this.slaveGone,
|
|
16121
16281
|
writable: true,
|
|
16122
|
-
hangup: this.slaveGone
|
|
16282
|
+
hangup: this.slaveGone,
|
|
16283
|
+
nread: this.queue.reduce((n, chunk2) => n + chunk2.length, 0)
|
|
16123
16284
|
}),
|
|
16124
16285
|
changed: (signal) => this.changed(signal),
|
|
16125
16286
|
close: () => this.closeMaster(),
|
|
@@ -16340,11 +16501,11 @@ async function runChild(req, deps) {
|
|
|
16340
16501
|
if (pid !== 0) kill();
|
|
16341
16502
|
decided.resolve();
|
|
16342
16503
|
};
|
|
16343
|
-
const
|
|
16504
|
+
const controls2 = [];
|
|
16344
16505
|
const capture = () => {
|
|
16345
16506
|
const { promise, resolve: resolve2 } = Promise.withResolvers();
|
|
16346
16507
|
const control = { shut: false, ended: resolve2, eof: promise };
|
|
16347
|
-
|
|
16508
|
+
controls2.push(control);
|
|
16348
16509
|
return { capture: true, max, overflow: () => stop("ENOBUFS"), control };
|
|
16349
16510
|
};
|
|
16350
16511
|
const decided = Promise.withResolvers();
|
|
@@ -16378,11 +16539,11 @@ async function runChild(req, deps) {
|
|
|
16378
16539
|
let status;
|
|
16379
16540
|
try {
|
|
16380
16541
|
status = await reaped(deps, pid);
|
|
16381
|
-
const open =
|
|
16542
|
+
const open = controls2.filter((c) => c.opened);
|
|
16382
16543
|
await Promise.race([Promise.all(open.map((c) => c.eof)), decided.promise]);
|
|
16383
16544
|
} finally {
|
|
16384
16545
|
cancel?.();
|
|
16385
|
-
for (const control of
|
|
16546
|
+
for (const control of controls2) control.shut = true;
|
|
16386
16547
|
}
|
|
16387
16548
|
const out = deps.children.captured(pid, 1);
|
|
16388
16549
|
const err = deps.children.captured(pid, 2);
|
|
@@ -16401,13 +16562,17 @@ async function runChild(req, deps) {
|
|
|
16401
16562
|
// src/kernel/select.ts
|
|
16402
16563
|
function ready(fds, read, write) {
|
|
16403
16564
|
const hangup = /* @__PURE__ */ new Set();
|
|
16565
|
+
const nread = {};
|
|
16404
16566
|
const pick = (list, dir) => list.filter((fd) => {
|
|
16405
16567
|
const state = pollFile(fds.get(fd).file);
|
|
16406
16568
|
if (state.hangup) hangup.add(fd);
|
|
16407
|
-
|
|
16569
|
+
const picked = state[dir] || state.hangup;
|
|
16570
|
+
if (picked && dir === "readable" && state.nread !== void 0) nread[fd] = state.nread;
|
|
16571
|
+
return picked;
|
|
16408
16572
|
});
|
|
16409
16573
|
const out = { read: pick(read, "readable"), write: pick(write, "writable") };
|
|
16410
16574
|
if (hangup.size > 0) out.hangup = [...hangup];
|
|
16575
|
+
if (Object.keys(nread).length > 0) out.nread = nread;
|
|
16411
16576
|
return out;
|
|
16412
16577
|
}
|
|
16413
16578
|
function interruption(signal) {
|
|
@@ -16964,6 +17129,47 @@ function encodeReceived(got) {
|
|
|
16964
17129
|
return out;
|
|
16965
17130
|
}
|
|
16966
17131
|
|
|
17132
|
+
// src/kernel/net/tls-ciphers.ts
|
|
17133
|
+
var SUITES = [
|
|
17134
|
+
[4865, "TLS_AES_128_GCM_SHA256", "TLS_AES_128_GCM_SHA256", "TLSv1.3"],
|
|
17135
|
+
[4866, "TLS_AES_256_GCM_SHA384", "TLS_AES_256_GCM_SHA384", "TLSv1.3"],
|
|
17136
|
+
[4867, "TLS_CHACHA20_POLY1305_SHA256", "TLS_CHACHA20_POLY1305_SHA256", "TLSv1.3"],
|
|
17137
|
+
[4868, "TLS_AES_128_CCM_SHA256", "TLS_AES_128_CCM_SHA256", "TLSv1.3"],
|
|
17138
|
+
[4869, "TLS_AES_128_CCM_8_SHA256", "TLS_AES_128_CCM_8_SHA256", "TLSv1.3"],
|
|
17139
|
+
[49195, "ECDHE-ECDSA-AES128-GCM-SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLSv1.2"],
|
|
17140
|
+
[49196, "ECDHE-ECDSA-AES256-GCM-SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLSv1.2"],
|
|
17141
|
+
[49199, "ECDHE-RSA-AES128-GCM-SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLSv1.2"],
|
|
17142
|
+
[49200, "ECDHE-RSA-AES256-GCM-SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLSv1.2"],
|
|
17143
|
+
[52392, "ECDHE-RSA-CHACHA20-POLY1305", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLSv1.2"],
|
|
17144
|
+
[
|
|
17145
|
+
52393,
|
|
17146
|
+
"ECDHE-ECDSA-CHACHA20-POLY1305",
|
|
17147
|
+
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
|
17148
|
+
"TLSv1.2"
|
|
17149
|
+
],
|
|
17150
|
+
[49187, "ECDHE-ECDSA-AES128-SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLSv1.2"],
|
|
17151
|
+
[49188, "ECDHE-ECDSA-AES256-SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "TLSv1.2"],
|
|
17152
|
+
[49191, "ECDHE-RSA-AES128-SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLSv1.2"],
|
|
17153
|
+
[49192, "ECDHE-RSA-AES256-SHA384", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLSv1.2"],
|
|
17154
|
+
[49161, "ECDHE-ECDSA-AES128-SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLSv1.0"],
|
|
17155
|
+
[49162, "ECDHE-ECDSA-AES256-SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLSv1.0"],
|
|
17156
|
+
[49171, "ECDHE-RSA-AES128-SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLSv1.0"],
|
|
17157
|
+
[49172, "ECDHE-RSA-AES256-SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLSv1.0"],
|
|
17158
|
+
[156, "AES128-GCM-SHA256", "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLSv1.2"],
|
|
17159
|
+
[157, "AES256-GCM-SHA384", "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLSv1.2"],
|
|
17160
|
+
[158, "DHE-RSA-AES128-GCM-SHA256", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "TLSv1.2"],
|
|
17161
|
+
[159, "DHE-RSA-AES256-GCM-SHA384", "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "TLSv1.2"]
|
|
17162
|
+
];
|
|
17163
|
+
function cipherOf(id2, protocol) {
|
|
17164
|
+
const known = SUITES.find(([n]) => n === id2);
|
|
17165
|
+
const hex3 = `0x${id2.toString(16).padStart(4, "0").toUpperCase()}`;
|
|
17166
|
+
return {
|
|
17167
|
+
name: known?.[1] ?? hex3,
|
|
17168
|
+
standardName: known?.[2] ?? hex3,
|
|
17169
|
+
version: known?.[3] ?? protocol
|
|
17170
|
+
};
|
|
17171
|
+
}
|
|
17172
|
+
|
|
16967
17173
|
// src/kernel/net/tls-client.ts
|
|
16968
17174
|
var WRITE_CHUNK = 16 * 1024;
|
|
16969
17175
|
var BADCERT = [
|
|
@@ -16980,6 +17186,15 @@ function verifyCode(flags2) {
|
|
|
16980
17186
|
if (flags2 === -1) return "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
|
|
16981
17187
|
return BADCERT.find(([bit]) => (flags2 & bit) !== 0)?.[1] ?? "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
|
|
16982
17188
|
}
|
|
17189
|
+
function isIP(name2) {
|
|
17190
|
+
return ipv4Bytes(name2) !== void 0 || name2.includes(":") && ipv6Groups(name2) !== void 0;
|
|
17191
|
+
}
|
|
17192
|
+
function clientFlags(o) {
|
|
17193
|
+
return (o.insecure ? TLS_CLIENT_INSECURE_SKIP_VERIFY : 0) | (o.sni === false ? TLS_CLIENT_NO_SNI : 0) | (o.checkHostname === false ? TLS_CLIENT_VERIFY_CHAIN_ONLY : 0);
|
|
17194
|
+
}
|
|
17195
|
+
function openSession(o) {
|
|
17196
|
+
return o.engine.clientSession(o.store, o.servername, o.alpn, clientFlags(o));
|
|
17197
|
+
}
|
|
16983
17198
|
var Ciphertext = class {
|
|
16984
17199
|
queue = [];
|
|
16985
17200
|
ended = false;
|
|
@@ -17052,17 +17267,39 @@ async function handshake(conn, o, session, inbox) {
|
|
|
17052
17267
|
}
|
|
17053
17268
|
}
|
|
17054
17269
|
}
|
|
17270
|
+
function controlsOf(o, session, protocol) {
|
|
17271
|
+
if (!o.engine.sessionControls) return {};
|
|
17272
|
+
const checked = o.checkHostname !== false && !o.insecure;
|
|
17273
|
+
return {
|
|
17274
|
+
cipher: cipherOf(session.ciphersuite, protocol),
|
|
17275
|
+
clientCertificate: o.clientCertificate === true,
|
|
17276
|
+
sni: o.sni !== false && !isIP(o.servername),
|
|
17277
|
+
hostnameChecked: checked,
|
|
17278
|
+
...o.insecure ? {} : { hostnameMatches: checked || !session.nameMismatch }
|
|
17279
|
+
};
|
|
17280
|
+
}
|
|
17055
17281
|
function infoOf(o, session) {
|
|
17056
17282
|
const flags2 = session.verifyResult;
|
|
17057
17283
|
const code = verifyCode(flags2);
|
|
17284
|
+
const protocol = session.version === 772 ? "TLSv1.3" : "TLSv1.2";
|
|
17058
17285
|
return {
|
|
17059
|
-
protocol
|
|
17286
|
+
protocol,
|
|
17060
17287
|
alpnProtocol: session.alpn ?? false,
|
|
17061
17288
|
authorized: code === void 0,
|
|
17062
17289
|
...code ? { authorizationError: code, authorizationText: o.engine.verifyInfo(flags2).trim() } : {},
|
|
17063
|
-
peerCertificates: session.peerChain()
|
|
17290
|
+
peerCertificates: session.peerChain(),
|
|
17291
|
+
...controlsOf(o, session, protocol)
|
|
17064
17292
|
};
|
|
17065
17293
|
}
|
|
17294
|
+
var FATAL_ALERT = -30592;
|
|
17295
|
+
function alerted(err) {
|
|
17296
|
+
if (err.code === FATAL_ALERT)
|
|
17297
|
+
return new KernelError(
|
|
17298
|
+
"EPROTO",
|
|
17299
|
+
`ERR_SSL_FATAL_ALERT: the server ended the session: ${err.message}`
|
|
17300
|
+
);
|
|
17301
|
+
return new KernelError("EPROTO", `ERR_SSL_PROTOCOL_ERROR: ${err.message}`);
|
|
17302
|
+
}
|
|
17066
17303
|
function plaintext(conn, session, inbox) {
|
|
17067
17304
|
let freed = false;
|
|
17068
17305
|
let writeClosed = false;
|
|
@@ -17077,7 +17314,12 @@ function plaintext(conn, session, inbox) {
|
|
|
17077
17314
|
async read() {
|
|
17078
17315
|
for (; ; ) {
|
|
17079
17316
|
if (freed) return null;
|
|
17080
|
-
|
|
17317
|
+
let got;
|
|
17318
|
+
try {
|
|
17319
|
+
got = session.read();
|
|
17320
|
+
} catch (err) {
|
|
17321
|
+
throw alerted(err);
|
|
17322
|
+
}
|
|
17081
17323
|
await send(conn, session);
|
|
17082
17324
|
if (got instanceof Uint8Array) return got;
|
|
17083
17325
|
if (got === "eof") return null;
|
|
@@ -17105,8 +17347,7 @@ function plaintext(conn, session, inbox) {
|
|
|
17105
17347
|
};
|
|
17106
17348
|
}
|
|
17107
17349
|
async function tlsClient(conn, o, taken = new Uint8Array(0)) {
|
|
17108
|
-
const
|
|
17109
|
-
const session = o.engine.clientSession(o.store, o.servername, o.alpn, flags2);
|
|
17350
|
+
const session = o.session ?? openSession(o);
|
|
17110
17351
|
const inbox = new Ciphertext(conn, session);
|
|
17111
17352
|
inbox.hand(taken);
|
|
17112
17353
|
try {
|
|
@@ -17119,10 +17360,10 @@ async function tlsClient(conn, o, taken = new Uint8Array(0)) {
|
|
|
17119
17360
|
}
|
|
17120
17361
|
|
|
17121
17362
|
// src/kernel/net/tls-uplink.ts
|
|
17122
|
-
var
|
|
17363
|
+
var isIP2 = (text) => ipv4Bytes(text) !== void 0 || text.includes(":") && ipv6Groups(text) !== void 0;
|
|
17123
17364
|
var LABEL2 = /^(?!-)[A-Za-z0-9-]{1,63}(?<!-)$/;
|
|
17124
17365
|
function serverName(name2) {
|
|
17125
|
-
if (
|
|
17366
|
+
if (isIP2(name2.replace(/^\[|\]$/g, ""))) return name2.replace(/^\[|\]$/g, "");
|
|
17126
17367
|
const bare = name2.endsWith(".") ? name2.slice(0, -1) : name2;
|
|
17127
17368
|
if (bare.length === 0 || bare.length > 253 || !bare.split(".").every((l) => LABEL2.test(l))) {
|
|
17128
17369
|
throw new KernelError(
|
|
@@ -17172,9 +17413,66 @@ function sessionOf(info, servername) {
|
|
|
17172
17413
|
authorizationText: info.authorizationText
|
|
17173
17414
|
} : {},
|
|
17174
17415
|
servername,
|
|
17175
|
-
peerCertificates: info.peerCertificates.map(encode)
|
|
17416
|
+
peerCertificates: info.peerCertificates.map(encode),
|
|
17417
|
+
...controls(info)
|
|
17176
17418
|
};
|
|
17177
17419
|
}
|
|
17420
|
+
function controls(info) {
|
|
17421
|
+
if (!info.cipher) return {};
|
|
17422
|
+
return {
|
|
17423
|
+
cipher: info.cipher,
|
|
17424
|
+
clientCertificate: info.clientCertificate === true,
|
|
17425
|
+
sni: info.sni !== false,
|
|
17426
|
+
hostnameChecked: info.hostnameChecked === true,
|
|
17427
|
+
...info.hostnameMatches === void 0 ? {} : { hostnameMatches: info.hostnameMatches }
|
|
17428
|
+
};
|
|
17429
|
+
}
|
|
17430
|
+
var KEY_ERRORS = [
|
|
17431
|
+
[-3, "ERR_OSSL_X509_KEY_VALUES_MISMATCH"],
|
|
17432
|
+
[-15232, "ERR_OSSL_BAD_DECRYPT"],
|
|
17433
|
+
[-15360, "ERR_OSSL_CRYPTO_INTERRUPTED_OR_CANCELLED"]
|
|
17434
|
+
];
|
|
17435
|
+
function keyRefused(err) {
|
|
17436
|
+
const code = err instanceof TlsError ? err.code : 0;
|
|
17437
|
+
const name2 = KEY_ERRORS.find(([n]) => n === code)?.[1] ?? "ERR_OSSL_UNSUPPORTED";
|
|
17438
|
+
const text = code === -3 ? "the key does not match the certificate" : err.message;
|
|
17439
|
+
return new KernelError("EPROTO", `${name2}: ${text}`);
|
|
17440
|
+
}
|
|
17441
|
+
function takeCert(req) {
|
|
17442
|
+
const cert = req.clientCert;
|
|
17443
|
+
if (!cert) return void 0;
|
|
17444
|
+
delete req.clientCert;
|
|
17445
|
+
if (!Array.isArray(cert.chain) || cert.chain.length === 0 || typeof cert.key !== "string")
|
|
17446
|
+
throw new KernelError("EINVAL", "ERR_INVALID_ARG_VALUE: cert and key go together");
|
|
17447
|
+
let ders;
|
|
17448
|
+
let key;
|
|
17449
|
+
try {
|
|
17450
|
+
ders = cert.chain.map(base64Der);
|
|
17451
|
+
key = base64Der(cert.key);
|
|
17452
|
+
} catch {
|
|
17453
|
+
throw new KernelError("EINVAL", "ERR_INVALID_ARG_VALUE: cert or key is not base64");
|
|
17454
|
+
}
|
|
17455
|
+
const chain2 = new Uint8Array(ders.reduce((n, d) => n + d.length, 0));
|
|
17456
|
+
let at = 0;
|
|
17457
|
+
for (const der of ders) {
|
|
17458
|
+
chain2.set(der, at);
|
|
17459
|
+
at += der.length;
|
|
17460
|
+
}
|
|
17461
|
+
const pass2 = new TextEncoder().encode(cert.passphrase ?? "");
|
|
17462
|
+
return { chain: chain2, key, pass: pass2 };
|
|
17463
|
+
}
|
|
17464
|
+
function withCert(session, cert) {
|
|
17465
|
+
if (!cert) return;
|
|
17466
|
+
try {
|
|
17467
|
+
session.ownCert(cert.chain, cert.key, cert.pass);
|
|
17468
|
+
} catch (err) {
|
|
17469
|
+
throw keyRefused(err);
|
|
17470
|
+
}
|
|
17471
|
+
}
|
|
17472
|
+
function wipe(cert) {
|
|
17473
|
+
cert?.key.fill(0);
|
|
17474
|
+
cert?.pass.fill(0);
|
|
17475
|
+
}
|
|
17178
17476
|
async function setUp(support, req) {
|
|
17179
17477
|
const engine = await support.engine();
|
|
17180
17478
|
if (!engine.client)
|
|
@@ -17192,21 +17490,66 @@ async function setUp(support, req) {
|
|
|
17192
17490
|
}
|
|
17193
17491
|
return { engine, store: own, own };
|
|
17194
17492
|
}
|
|
17195
|
-
function
|
|
17196
|
-
|
|
17197
|
-
|
|
17493
|
+
async function prepare(support, req, servername) {
|
|
17494
|
+
const cert = takeCert(req);
|
|
17495
|
+
try {
|
|
17496
|
+
return await prepareWith(support, req, servername, cert);
|
|
17497
|
+
} catch (err) {
|
|
17498
|
+
if (err instanceof KernelError) throw err;
|
|
17499
|
+
throw new KernelError("ENOTSUP", err instanceof Error ? err.message : String(err));
|
|
17500
|
+
} finally {
|
|
17501
|
+
wipe(cert);
|
|
17502
|
+
}
|
|
17503
|
+
}
|
|
17504
|
+
async function prepareWith(support, req, servername, cert) {
|
|
17505
|
+
if (req.checkHostname === false && req.insecure === true) {
|
|
17506
|
+
throw new KernelError(
|
|
17507
|
+
"EINVAL",
|
|
17508
|
+
"ERR_INVALID_ARG_VALUE: checkHostname: false needs rejectUnauthorized"
|
|
17509
|
+
);
|
|
17510
|
+
}
|
|
17511
|
+
const { engine, store, own } = await setUp(support, req);
|
|
17512
|
+
const options = {
|
|
17513
|
+
engine,
|
|
17514
|
+
store,
|
|
17515
|
+
servername,
|
|
17516
|
+
alpn: req.alpn ?? [],
|
|
17517
|
+
insecure: req.insecure === true,
|
|
17518
|
+
...req.sni === false ? { sni: false } : {},
|
|
17519
|
+
...req.checkHostname === false ? { checkHostname: false } : {},
|
|
17520
|
+
clientCertificate: cert !== void 0
|
|
17521
|
+
};
|
|
17522
|
+
let session;
|
|
17523
|
+
try {
|
|
17524
|
+
const controls2 = req.sni === false || req.checkHostname === false || cert !== void 0;
|
|
17525
|
+
if (controls2 && !engine.sessionControls) {
|
|
17526
|
+
throw new KernelError("ENOTSUP", "the installed tls engine has no client certificates");
|
|
17527
|
+
}
|
|
17528
|
+
session = openSession(options);
|
|
17529
|
+
withCert(session, cert);
|
|
17530
|
+
return { options: { ...options, session }, own };
|
|
17531
|
+
} catch (err) {
|
|
17532
|
+
session?.free();
|
|
17533
|
+
own?.release();
|
|
17534
|
+
throw err;
|
|
17535
|
+
}
|
|
17536
|
+
}
|
|
17537
|
+
function secure(prepared) {
|
|
17538
|
+
let ran = false;
|
|
17539
|
+
const make = async (raw) => {
|
|
17540
|
+
ran = true;
|
|
17198
17541
|
try {
|
|
17199
|
-
return await tlsClient(raw,
|
|
17200
|
-
engine,
|
|
17201
|
-
store,
|
|
17202
|
-
servername,
|
|
17203
|
-
alpn: req.alpn ?? [],
|
|
17204
|
-
insecure: req.insecure === true
|
|
17205
|
-
});
|
|
17542
|
+
return await tlsClient(raw, prepared.options);
|
|
17206
17543
|
} finally {
|
|
17207
|
-
own?.release();
|
|
17544
|
+
prepared.own?.release();
|
|
17208
17545
|
}
|
|
17209
17546
|
};
|
|
17547
|
+
const abandon = () => {
|
|
17548
|
+
if (ran) return;
|
|
17549
|
+
prepared.options.session.free();
|
|
17550
|
+
prepared.own?.release();
|
|
17551
|
+
};
|
|
17552
|
+
return { make, abandon };
|
|
17210
17553
|
}
|
|
17211
17554
|
function supportOf(net) {
|
|
17212
17555
|
const support = net.tlsClient;
|
|
@@ -17215,7 +17558,7 @@ function supportOf(net) {
|
|
|
17215
17558
|
}
|
|
17216
17559
|
async function uplinkAddress(proc, host) {
|
|
17217
17560
|
const bare = host.replace(/^\[|\]$/g, "");
|
|
17218
|
-
if (
|
|
17561
|
+
if (isIP2(bare)) return bare;
|
|
17219
17562
|
const [first] = await proc.resolve(host, 0, () => proc.blocking());
|
|
17220
17563
|
if (!first) throw new KernelError("ENOENT", `ENOTFOUND: ${host}`);
|
|
17221
17564
|
return first;
|
|
@@ -17224,23 +17567,31 @@ async function connectSecure(proc, socket, host, port, req) {
|
|
|
17224
17567
|
const servername = serverName(req.servername || host);
|
|
17225
17568
|
if (isLoopbackHost(servername) || isLoopbackHost(host)) throw new KernelError("ENOTSUP");
|
|
17226
17569
|
const address = await uplinkAddress(proc, host);
|
|
17227
|
-
const
|
|
17228
|
-
if (!
|
|
17570
|
+
const route2 = proc.net.uplinkFor(address);
|
|
17571
|
+
if (!route2)
|
|
17229
17572
|
throw new KernelError("ENOTSUP", "TLS in the kernel needs a destination the uplink routes");
|
|
17230
17573
|
const support = supportOf(proc.net);
|
|
17231
17574
|
let info;
|
|
17232
|
-
const make = secure(support, req, servername);
|
|
17233
|
-
|
|
17234
|
-
|
|
17235
|
-
|
|
17575
|
+
const { make, abandon } = secure(await prepare(support, req, servername));
|
|
17576
|
+
try {
|
|
17577
|
+
await socket.connectSecure({ family: "inet", host: address, port }, route2, async (conn) => {
|
|
17578
|
+
info = await conn.upgrade(make);
|
|
17579
|
+
});
|
|
17580
|
+
} finally {
|
|
17581
|
+
abandon();
|
|
17582
|
+
}
|
|
17236
17583
|
return sessionOf(info, servername);
|
|
17237
17584
|
}
|
|
17238
17585
|
async function upgradeSecure(proc, socket, req) {
|
|
17239
17586
|
const peer = socket.peer;
|
|
17240
17587
|
const host = req.servername || (peer?.family === "inet" ? peer.host : "");
|
|
17241
17588
|
const servername = serverName(host);
|
|
17242
|
-
const
|
|
17243
|
-
|
|
17589
|
+
const { make, abandon } = secure(await prepare(supportOf(proc.net), req, servername));
|
|
17590
|
+
try {
|
|
17591
|
+
return sessionOf(await socket.upgradeSecure(make), servername);
|
|
17592
|
+
} finally {
|
|
17593
|
+
abandon();
|
|
17594
|
+
}
|
|
17244
17595
|
}
|
|
17245
17596
|
|
|
17246
17597
|
// src/kernel/unix-dgram.ts
|
|
@@ -17602,17 +17953,23 @@ var NOT_HTTP_PORTS = /* @__PURE__ */ new Set([
|
|
|
17602
17953
|
8883
|
|
17603
17954
|
]);
|
|
17604
17955
|
var HOST_NAME = /^[A-Za-z0-9.-]+$|^\[?[0-9A-Fa-f:.]+\]?$/;
|
|
17956
|
+
function sessionControls(req) {
|
|
17957
|
+
return req.sni === false || req.checkHostname === false || req.clientCert !== void 0;
|
|
17958
|
+
}
|
|
17605
17959
|
function wantsKernel(req) {
|
|
17606
17960
|
if (req.path === "kernel") return true;
|
|
17607
17961
|
if (req.path === "transport") return false;
|
|
17608
|
-
return Array.isArray(req.ca) || req.alpn !== void 0 && req.alpn.length > 0 && !req.alpn.includes("http/1.1") || NOT_HTTP_PORTS.has(req.port);
|
|
17962
|
+
return Array.isArray(req.ca) || sessionControls(req) || req.alpn !== void 0 && req.alpn.length > 0 && !req.alpn.includes("http/1.1") || NOT_HTTP_PORTS.has(req.port);
|
|
17609
17963
|
}
|
|
17610
17964
|
async function secureConnect(req, proc) {
|
|
17611
17965
|
if (!Number.isInteger(req.port) || req.port < 1 || req.port > 65535)
|
|
17612
17966
|
throw new KernelError("EINVAL");
|
|
17613
17967
|
const kernelPath = wantsKernel(req) && await uplinked(proc, req.host);
|
|
17614
17968
|
if (!kernelPath) {
|
|
17615
|
-
if (req.path === "kernel" || Array.isArray(req.ca)
|
|
17969
|
+
if (req.path === "kernel" || Array.isArray(req.ca) || sessionControls(req)) {
|
|
17970
|
+
delete req.clientCert;
|
|
17971
|
+
throw new KernelError("ENOTSUP");
|
|
17972
|
+
}
|
|
17616
17973
|
return { ...tlsOverTransport(req, proc), path: "transport", substitutes: true };
|
|
17617
17974
|
}
|
|
17618
17975
|
const socket = proc.net.socket("inet");
|
|
@@ -17746,13 +18103,17 @@ var VfsNode = class {
|
|
|
17746
18103
|
const ranged2 = await this.prepare();
|
|
17747
18104
|
await ranged2?.pin();
|
|
17748
18105
|
}
|
|
18106
|
+
moving = /* @__PURE__ */ new Set();
|
|
17749
18107
|
async load() {
|
|
17750
18108
|
if (this.revoked) throw new KernelError("EIO");
|
|
17751
|
-
|
|
18109
|
+
while (!this.data) {
|
|
18110
|
+
const at = this.path;
|
|
17752
18111
|
try {
|
|
17753
|
-
this.data = await this.fs.readFileBuffer(
|
|
18112
|
+
this.data = await this.fs.readFileBuffer(at);
|
|
17754
18113
|
} catch (err) {
|
|
17755
18114
|
if (!isMissing(err)) throw err;
|
|
18115
|
+
while (this.moving.size > 0) await Promise.all(this.moving);
|
|
18116
|
+
if (this.path !== at) continue;
|
|
17756
18117
|
this.data = new Uint8Array(0);
|
|
17757
18118
|
this.missing = true;
|
|
17758
18119
|
}
|
|
@@ -18106,6 +18467,16 @@ var VfsNodes = class {
|
|
|
18106
18467
|
this.byPath.set(file.hidden, node);
|
|
18107
18468
|
this.kept.set(node, file);
|
|
18108
18469
|
}
|
|
18470
|
+
moving(path) {
|
|
18471
|
+
const node = this.byPath.get(path);
|
|
18472
|
+
if (!node) return () => void 0;
|
|
18473
|
+
const { promise, resolve: resolve2 } = Promise.withResolvers();
|
|
18474
|
+
node.moving.add(promise);
|
|
18475
|
+
return () => {
|
|
18476
|
+
node.moving.delete(promise);
|
|
18477
|
+
resolve2();
|
|
18478
|
+
};
|
|
18479
|
+
}
|
|
18109
18480
|
unkeep(path, file) {
|
|
18110
18481
|
const node = this.byPath.get(file.hidden);
|
|
18111
18482
|
if (!node) return;
|
|
@@ -18414,6 +18785,65 @@ function vfsFile(fs, opts, nodes) {
|
|
|
18414
18785
|
});
|
|
18415
18786
|
}
|
|
18416
18787
|
|
|
18788
|
+
// src/kernel/watch-ops.ts
|
|
18789
|
+
var WATCH_OPS = ["watch-open", "watch-next", "watch-close"];
|
|
18790
|
+
var WATCHING = new Set(WATCH_OPS);
|
|
18791
|
+
function isWatchSyscall(req) {
|
|
18792
|
+
return WATCHING.has(req.op);
|
|
18793
|
+
}
|
|
18794
|
+
var WATCHES_MAX = 8192;
|
|
18795
|
+
var parentOf8 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
|
|
18796
|
+
function visibleTo2(watch, root, visible) {
|
|
18797
|
+
return {
|
|
18798
|
+
close: () => watch.close(),
|
|
18799
|
+
next: async (signal) => {
|
|
18800
|
+
const notes = await watch.next(signal);
|
|
18801
|
+
const seen = /* @__PURE__ */ new Map();
|
|
18802
|
+
const shown = await Promise.all(
|
|
18803
|
+
notes.map(async (note) => {
|
|
18804
|
+
if (!("filename" in note) || !note.filename.includes("/")) return true;
|
|
18805
|
+
const dir = parentOf8(`${root === "/" ? "" : root}/${note.filename}`);
|
|
18806
|
+
if (!seen.has(dir)) seen.set(dir, visible(dir));
|
|
18807
|
+
return seen.get(dir);
|
|
18808
|
+
})
|
|
18809
|
+
);
|
|
18810
|
+
return notes.filter((_note, i) => shown[i]);
|
|
18811
|
+
}
|
|
18812
|
+
};
|
|
18813
|
+
}
|
|
18814
|
+
var ProcessWatches = class {
|
|
18815
|
+
open = /* @__PURE__ */ new Map();
|
|
18816
|
+
nextId = 1;
|
|
18817
|
+
source;
|
|
18818
|
+
constructor(source) {
|
|
18819
|
+
this.source = source;
|
|
18820
|
+
}
|
|
18821
|
+
async syscall(req, cancelled) {
|
|
18822
|
+
if (req.op === "watch-open") {
|
|
18823
|
+
if (!this.source) throw new KernelError("ENOSYS");
|
|
18824
|
+
if (this.open.size >= WATCHES_MAX) throw new KernelError("ENOSPC");
|
|
18825
|
+
const watch2 = await this.source.open(req.path, req.recursive === true);
|
|
18826
|
+
const id2 = this.nextId++;
|
|
18827
|
+
this.open.set(id2, watch2);
|
|
18828
|
+
return { ok: true, kind: "json", json: id2 };
|
|
18829
|
+
}
|
|
18830
|
+
const watch = this.open.get(req.id);
|
|
18831
|
+
if (req.op === "watch-close") {
|
|
18832
|
+
watch?.close();
|
|
18833
|
+
this.open.delete(req.id);
|
|
18834
|
+
return { ok: true, kind: "void" };
|
|
18835
|
+
}
|
|
18836
|
+
if (!watch) return { ok: true, kind: "json", json: [{ ended: true }] };
|
|
18837
|
+
const notes = await watch.next(cancelled);
|
|
18838
|
+
if (notes.some((note) => "ended" in note)) this.open.delete(req.id);
|
|
18839
|
+
return { ok: true, kind: "json", json: notes };
|
|
18840
|
+
}
|
|
18841
|
+
closeAll() {
|
|
18842
|
+
for (const watch of this.open.values()) watch.close();
|
|
18843
|
+
this.open.clear();
|
|
18844
|
+
}
|
|
18845
|
+
};
|
|
18846
|
+
|
|
18417
18847
|
// src/kernel/process.ts
|
|
18418
18848
|
function aborted(signal) {
|
|
18419
18849
|
return new Promise((_, reject) => {
|
|
@@ -18540,7 +18970,8 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
|
|
|
18540
18970
|
...SEM_OPS,
|
|
18541
18971
|
...HTTP_OPS,
|
|
18542
18972
|
...PTY_OPS,
|
|
18543
|
-
...HOST_OPS
|
|
18973
|
+
...HOST_OPS,
|
|
18974
|
+
...WATCH_OPS
|
|
18544
18975
|
]);
|
|
18545
18976
|
function isWasmSyscall(req) {
|
|
18546
18977
|
const op = req.op;
|
|
@@ -18592,6 +19023,7 @@ function timeLeft(req, started) {
|
|
|
18592
19023
|
}
|
|
18593
19024
|
var WasmProcess = class {
|
|
18594
19025
|
exited = false;
|
|
19026
|
+
watches;
|
|
18595
19027
|
children;
|
|
18596
19028
|
deathSignals = /* @__PURE__ */ new Map();
|
|
18597
19029
|
caught = 0;
|
|
@@ -18622,6 +19054,7 @@ var WasmProcess = class {
|
|
|
18622
19054
|
this.pid = pid;
|
|
18623
19055
|
this.fds = fds;
|
|
18624
19056
|
this.options = options;
|
|
19057
|
+
this.watches = new ProcessWatches(options.watches);
|
|
18625
19058
|
this.inherited = options.ignored ?? 0;
|
|
18626
19059
|
this.umask = options.umask ?? DEFAULT_UMASK2;
|
|
18627
19060
|
this.cred = copyCred(options.cred ?? ROOT);
|
|
@@ -18879,6 +19312,7 @@ var WasmProcess = class {
|
|
|
18879
19312
|
});
|
|
18880
19313
|
}
|
|
18881
19314
|
if (isHttpSyscall(req)) return await this.httpSyscall(req);
|
|
19315
|
+
if (isWatchSyscall(req)) return await this.watches.syscall(req, cancelled);
|
|
18882
19316
|
if (isHostSyscall(req)) {
|
|
18883
19317
|
return await hostSyscall(req, {
|
|
18884
19318
|
pid: this.pid,
|
|
@@ -20019,6 +20453,7 @@ var WasmProcess = class {
|
|
|
20019
20453
|
this.options.locks?.release(this.pid);
|
|
20020
20454
|
for (const owner of this.lockOwners) this.options.locks?.release(owner);
|
|
20021
20455
|
this.asyncOps.close();
|
|
20456
|
+
this.watches.closeAll();
|
|
20022
20457
|
for (const [target, sig] of this.deathSignals) this.sendDeath(target, sig);
|
|
20023
20458
|
this.deathSignals.clear();
|
|
20024
20459
|
for (const pid of this.children.pids()) this.options.onReap?.(pid);
|
|
@@ -20280,6 +20715,7 @@ function processOptions(opts, header4, hooks, created3) {
|
|
|
20280
20715
|
locks: opts.locks,
|
|
20281
20716
|
fifos: opts.fifos,
|
|
20282
20717
|
...opts.sems ? { sems: opts.sems } : {},
|
|
20718
|
+
watches: opts.watches,
|
|
20283
20719
|
onReap: opts.onReap,
|
|
20284
20720
|
resolver: opts.resolver,
|
|
20285
20721
|
...notifiers(header4),
|
|
@@ -21393,7 +21829,7 @@ function register(automaton, sources, ids, bytes, source) {
|
|
|
21393
21829
|
}
|
|
21394
21830
|
sources[id2].push(source);
|
|
21395
21831
|
}
|
|
21396
|
-
function
|
|
21832
|
+
function prepare2(secrets) {
|
|
21397
21833
|
const main = new Automaton();
|
|
21398
21834
|
const wrap = new Automaton();
|
|
21399
21835
|
const sources = [];
|
|
@@ -21544,7 +21980,7 @@ function merge(into, from) {
|
|
|
21544
21980
|
}
|
|
21545
21981
|
}
|
|
21546
21982
|
function compile(secrets, options = {}) {
|
|
21547
|
-
const c =
|
|
21983
|
+
const c = prepare2(secrets.map((secret) => ({ ...secret })));
|
|
21548
21984
|
const decoder4 = new TextDecoder();
|
|
21549
21985
|
const idleMs = options.idleMs ?? 250;
|
|
21550
21986
|
const scrubBytes = (input) => {
|
|
@@ -25565,6 +26001,7 @@ var Launcher = class {
|
|
|
25565
26001
|
locks: this.locks,
|
|
25566
26002
|
fifos: this.fifos,
|
|
25567
26003
|
sems: this.sems,
|
|
26004
|
+
watches: this.watchSource(pid),
|
|
25568
26005
|
resolver: this.resolver,
|
|
25569
26006
|
onReap: (child) => this.reaped(child, pid),
|
|
25570
26007
|
...req.fork ? { fork: req.fork } : {},
|
|
@@ -26108,6 +26545,23 @@ var Launcher = class {
|
|
|
26108
26545
|
mounts: this.mounts.list().map((entry) => entry.target).filter((target) => this.mounts.mounted(target) !== void 0)
|
|
26109
26546
|
});
|
|
26110
26547
|
}
|
|
26548
|
+
watchSource(pid) {
|
|
26549
|
+
return {
|
|
26550
|
+
open: async (path, recursive) => {
|
|
26551
|
+
const at = normalizePath(path);
|
|
26552
|
+
const g = this.execGuard(this.credOf(pid), pid);
|
|
26553
|
+
if (g) await readable(g, "watch", at);
|
|
26554
|
+
const st = await this.fs.stat(at);
|
|
26555
|
+
const real = await this.fs.realpath?.(at, true).catch(() => at) ?? at;
|
|
26556
|
+
const watch = this.watchers.typedWatch(real, recursive && st.isDirectory, at);
|
|
26557
|
+
if (!g || g.cred.euid === 0) return watch;
|
|
26558
|
+
return visibleTo2(watch, real, async (dir) => {
|
|
26559
|
+
const walked = await access(g.fs, g.cred, dir, R_OK | X_OK, { directory: true });
|
|
26560
|
+
return walked.denied === void 0 && walked.missing !== true;
|
|
26561
|
+
});
|
|
26562
|
+
}
|
|
26563
|
+
};
|
|
26564
|
+
}
|
|
26111
26565
|
watchFiles(paths, notify) {
|
|
26112
26566
|
this.fileWatches ??= new FileWatches(this.watchers, this.rootFs);
|
|
26113
26567
|
return this.fileWatches.watch(paths, notify);
|
|
@@ -26549,7 +27003,7 @@ function cronLocks() {
|
|
|
26549
27003
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
26550
27004
|
import { subscribe } from "node:diagnostics_channel";
|
|
26551
27005
|
import { lookup as lookup2 } from "node:dns/promises";
|
|
26552
|
-
import { isIP as
|
|
27006
|
+
import { isIP as isIP3 } from "node:net";
|
|
26553
27007
|
var DEVTOOLS_PORTS = [9222, 9223, 9224, 9225, 9226, 9227, 9228, 9229];
|
|
26554
27008
|
var METADATA_V6 = [64768, 3778, 0, 0, 0, 0, 0, 596].join(":");
|
|
26555
27009
|
var resolveHost = async (host) => (await lookup2(host, { all: true, verbatim: true })).map((a) => a.address);
|
|
@@ -26561,7 +27015,7 @@ function ipv4Place(address) {
|
|
|
26561
27015
|
}
|
|
26562
27016
|
function placeOf(address) {
|
|
26563
27017
|
const plain2 = address.replace(/^\[(.*)\]$/, "$1").toLowerCase();
|
|
26564
|
-
const kind =
|
|
27018
|
+
const kind = isIP3(plain2);
|
|
26565
27019
|
if (kind === 4) return ipv4Place(plain2);
|
|
26566
27020
|
if (kind !== 6) return void 0;
|
|
26567
27021
|
const words2 = hextets2(plain2);
|
|
@@ -26614,7 +27068,7 @@ function connectRefusal(address, port, place) {
|
|
|
26614
27068
|
}
|
|
26615
27069
|
async function addressesOf(host, resolve2) {
|
|
26616
27070
|
const plain2 = host.replace(/^\[(.*)\]$/, "$1");
|
|
26617
|
-
if (
|
|
27071
|
+
if (isIP3(plain2)) return [plain2];
|
|
26618
27072
|
if (loopbackName2(plain2)) return ["127.0.0.1"];
|
|
26619
27073
|
return resolve2(plain2).catch(() => []);
|
|
26620
27074
|
}
|
|
@@ -26949,7 +27403,7 @@ function isMemoryRoot(handle) {
|
|
|
26949
27403
|
|
|
26950
27404
|
// src/node/ws-diagnose.ts
|
|
26951
27405
|
import { lookup as lookup3 } from "node:dns/promises";
|
|
26952
|
-
import { isIP as
|
|
27406
|
+
import { isIP as isIP4, connect as tcp } from "node:net";
|
|
26953
27407
|
import { connect as tls } from "node:tls";
|
|
26954
27408
|
var PROBE_MS = 3e3;
|
|
26955
27409
|
var PASSED = /* @__PURE__ */ new Set(["ECONNREFUSED", "EHOSTUNREACH", "ENETUNREACH", "ETIMEDOUT", "ECONNRESET"]);
|
|
@@ -26971,7 +27425,7 @@ function abortable(work, signal) {
|
|
|
26971
27425
|
}
|
|
26972
27426
|
function probe(secure2, host, port, ms, signal) {
|
|
26973
27427
|
return new Promise((resolve2) => {
|
|
26974
|
-
const socket = secure2 ? tls({ host, port, ...
|
|
27428
|
+
const socket = secure2 ? tls({ host, port, ...isIP4(host) ? {} : { servername: host } }) : tcp({ host, port });
|
|
26975
27429
|
const stop = () => done4("ABORTED");
|
|
26976
27430
|
const done4 = (code) => {
|
|
26977
27431
|
clearTimeout(timer);
|