@ai-ecoverse/slicc-kernel 1.123.2 → 1.124.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 +27 -6
- package/dist/kernel-worker.js +694 -95
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +88 -18
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +724 -125
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +88 -18
- package/dist/process-worker.js.map +3 -3
- package/dist/types/fs/unlinked.d.ts +2 -1
- package/dist/types/kernel/fd-table.d.ts +1 -1
- package/dist/types/kernel/host-ops.d.ts +1 -0
- package/dist/types/kernel/lock-service.d.ts +4 -0
- package/dist/types/kernel/locks.d.ts +3 -0
- package/dist/types/kernel/net/network.d.ts +2 -0
- package/dist/types/kernel/net/switch-conn.d.ts +28 -0
- package/dist/types/kernel/net/tls-client.d.ts +22 -0
- package/dist/types/kernel/net/tls-engine.d.ts +27 -0
- package/dist/types/kernel/net/tls-uplink.d.ts +35 -0
- package/dist/types/kernel/socket-syscalls.d.ts +10 -1
- package/dist/types/kernel/socket.d.ts +13 -1
- package/dist/types/process/js/js-net.d.ts +10 -4
- package/package.json +3 -3
package/dist/node.js
CHANGED
|
@@ -1404,6 +1404,111 @@ var Routes = class {
|
|
|
1404
1404
|
}
|
|
1405
1405
|
};
|
|
1406
1406
|
|
|
1407
|
+
// src/kernel/net/switch-conn.ts
|
|
1408
|
+
var SwitchConn = class {
|
|
1409
|
+
raw;
|
|
1410
|
+
box = [];
|
|
1411
|
+
pulling = false;
|
|
1412
|
+
waiters = [];
|
|
1413
|
+
switching = false;
|
|
1414
|
+
secure;
|
|
1415
|
+
failed;
|
|
1416
|
+
constructor(raw) {
|
|
1417
|
+
this.raw = raw;
|
|
1418
|
+
}
|
|
1419
|
+
get localAddr() {
|
|
1420
|
+
return this.raw.localAddr;
|
|
1421
|
+
}
|
|
1422
|
+
get remoteAddr() {
|
|
1423
|
+
return this.raw.remoteAddr;
|
|
1424
|
+
}
|
|
1425
|
+
get upgraded() {
|
|
1426
|
+
return this.switching || this.secure !== void 0;
|
|
1427
|
+
}
|
|
1428
|
+
wake() {
|
|
1429
|
+
for (const wake of this.waiters.splice(0)) wake();
|
|
1430
|
+
}
|
|
1431
|
+
changed() {
|
|
1432
|
+
return new Promise((resolve2) => this.waiters.push(resolve2));
|
|
1433
|
+
}
|
|
1434
|
+
pull() {
|
|
1435
|
+
if (this.pulling || this.box.length > 0) return;
|
|
1436
|
+
this.pulling = true;
|
|
1437
|
+
this.raw.read().then(
|
|
1438
|
+
(bytes) => this.box.push(bytes),
|
|
1439
|
+
(err) => this.box.push(err instanceof Error ? err : new Error(String(err)))
|
|
1440
|
+
).finally(() => {
|
|
1441
|
+
this.pulling = false;
|
|
1442
|
+
this.wake();
|
|
1443
|
+
});
|
|
1444
|
+
}
|
|
1445
|
+
take() {
|
|
1446
|
+
const next3 = this.box.shift();
|
|
1447
|
+
if (next3 instanceof Error) throw next3;
|
|
1448
|
+
return next3;
|
|
1449
|
+
}
|
|
1450
|
+
async rawRead() {
|
|
1451
|
+
while (this.box.length === 0) {
|
|
1452
|
+
this.pull();
|
|
1453
|
+
await this.changed();
|
|
1454
|
+
}
|
|
1455
|
+
return this.take();
|
|
1456
|
+
}
|
|
1457
|
+
async read() {
|
|
1458
|
+
for (; ; ) {
|
|
1459
|
+
if (this.failed) throw this.failed;
|
|
1460
|
+
if (this.secure) return this.secure.read();
|
|
1461
|
+
if (!this.switching && this.box.length > 0) return this.take();
|
|
1462
|
+
if (!this.switching) this.pull();
|
|
1463
|
+
await this.changed();
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
async settled() {
|
|
1467
|
+
while (this.switching) await this.changed();
|
|
1468
|
+
if (this.failed) throw this.failed;
|
|
1469
|
+
return this.secure ?? this.raw;
|
|
1470
|
+
}
|
|
1471
|
+
async write(bytes) {
|
|
1472
|
+
return (await this.settled()).write(bytes);
|
|
1473
|
+
}
|
|
1474
|
+
closeWrite() {
|
|
1475
|
+
void this.settled().then(
|
|
1476
|
+
(conn) => conn.closeWrite(),
|
|
1477
|
+
() => void 0
|
|
1478
|
+
);
|
|
1479
|
+
}
|
|
1480
|
+
close() {
|
|
1481
|
+
this.failed ??= new Error("closed");
|
|
1482
|
+
this.secure?.close();
|
|
1483
|
+
this.raw.close();
|
|
1484
|
+
this.wake();
|
|
1485
|
+
}
|
|
1486
|
+
async upgrade(make) {
|
|
1487
|
+
if (this.upgraded) throw new Error("already upgraded");
|
|
1488
|
+
this.switching = true;
|
|
1489
|
+
this.wake();
|
|
1490
|
+
const view2 = {
|
|
1491
|
+
localAddr: this.raw.localAddr,
|
|
1492
|
+
remoteAddr: this.raw.remoteAddr,
|
|
1493
|
+
read: () => this.rawRead(),
|
|
1494
|
+
write: (bytes) => this.raw.write(bytes),
|
|
1495
|
+
closeWrite: () => this.raw.closeWrite(),
|
|
1496
|
+
close: () => this.raw.close()
|
|
1497
|
+
};
|
|
1498
|
+
try {
|
|
1499
|
+
const { conn, info } = await make(view2);
|
|
1500
|
+
this.secure = conn;
|
|
1501
|
+
return info;
|
|
1502
|
+
} catch (err) {
|
|
1503
|
+
this.failed = err instanceof Error ? err : new Error(String(err));
|
|
1504
|
+
throw err;
|
|
1505
|
+
} finally {
|
|
1506
|
+
this.switching = false;
|
|
1507
|
+
this.wake();
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
};
|
|
1511
|
+
|
|
1407
1512
|
// src/kernel/net/uplink-socket.ts
|
|
1408
1513
|
var CHUNK = 64 * 1024;
|
|
1409
1514
|
function hostPort(text) {
|
|
@@ -1728,7 +1833,18 @@ var KernelSocket = class _KernelSocket {
|
|
|
1728
1833
|
clearTimeout(timer);
|
|
1729
1834
|
}
|
|
1730
1835
|
}
|
|
1731
|
-
|
|
1836
|
+
switch;
|
|
1837
|
+
connectSecure(addr, route, secure2) {
|
|
1838
|
+
if (this.state !== "open") throw new KernelError("EISCONN");
|
|
1839
|
+
return this.dial(addr, route, secure2);
|
|
1840
|
+
}
|
|
1841
|
+
upgradeSecure(make) {
|
|
1842
|
+
if (this.state !== "connected") throw new KernelError("ENOTCONN");
|
|
1843
|
+
if (!this.switch) throw new KernelError("EOPNOTSUPP");
|
|
1844
|
+
if (this.switch.upgraded || this.writeShut || this.readShut) throw new KernelError("EINVAL");
|
|
1845
|
+
return this.switch.upgrade(make);
|
|
1846
|
+
}
|
|
1847
|
+
dial(addr, route, secure2) {
|
|
1732
1848
|
this.state = "connecting";
|
|
1733
1849
|
const abort = new AbortController();
|
|
1734
1850
|
this.dialing = abort;
|
|
@@ -1749,11 +1865,25 @@ var KernelSocket = class _KernelSocket {
|
|
|
1749
1865
|
() => void 0
|
|
1750
1866
|
);
|
|
1751
1867
|
return Promise.race([dialled, abandoned]).then(
|
|
1752
|
-
(
|
|
1868
|
+
async (raw) => {
|
|
1753
1869
|
if (abort.signal.aborted) throw dialError(abort.signal.reason, timedOut, true);
|
|
1870
|
+
const conn = new SwitchConn(raw);
|
|
1871
|
+
if (secure2) {
|
|
1872
|
+
clearTimeout(timer);
|
|
1873
|
+
try {
|
|
1874
|
+
await Promise.race([secure2(conn), abandoned]);
|
|
1875
|
+
} catch (e) {
|
|
1876
|
+
conn.close();
|
|
1877
|
+
throw this.dialFailed(
|
|
1878
|
+
abort,
|
|
1879
|
+
e instanceof KernelError ? e : new KernelError("ENOTSUP", e instanceof Error ? e.message : String(e))
|
|
1880
|
+
);
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1754
1883
|
this.local = { family: "inet", host: "0.0.0.0", port: 0, ...hostPort(conn.localAddr) };
|
|
1755
1884
|
this.peer = { ...addr, ...hostPort(conn.remoteAddr) };
|
|
1756
1885
|
this.dialing = void 0;
|
|
1886
|
+
this.switch = conn;
|
|
1757
1887
|
this.attach(
|
|
1758
1888
|
uplinkLink(conn, () => {
|
|
1759
1889
|
this.reset = true;
|
|
@@ -1762,17 +1892,19 @@ var KernelSocket = class _KernelSocket {
|
|
|
1762
1892
|
);
|
|
1763
1893
|
},
|
|
1764
1894
|
(e) => {
|
|
1765
|
-
|
|
1766
|
-
if (this.dialing === abort) {
|
|
1767
|
-
this.dialing = void 0;
|
|
1768
|
-
this.failed = error.code;
|
|
1769
|
-
this.state = "open";
|
|
1770
|
-
this.changes.wake();
|
|
1771
|
-
}
|
|
1772
|
-
throw error;
|
|
1895
|
+
throw this.dialFailed(abort, dialError(e, timedOut, abort.signal.aborted));
|
|
1773
1896
|
}
|
|
1774
1897
|
).finally(() => clearTimeout(timer));
|
|
1775
1898
|
}
|
|
1899
|
+
dialFailed(abort, error) {
|
|
1900
|
+
if (this.dialing === abort) {
|
|
1901
|
+
this.dialing = void 0;
|
|
1902
|
+
this.failed = error.code;
|
|
1903
|
+
this.state = "open";
|
|
1904
|
+
this.changes.wake();
|
|
1905
|
+
}
|
|
1906
|
+
return error;
|
|
1907
|
+
}
|
|
1776
1908
|
unlink() {
|
|
1777
1909
|
const link2 = this.link;
|
|
1778
1910
|
if (link2) {
|
|
@@ -1878,6 +2010,7 @@ var LoopbackNet = class {
|
|
|
1878
2010
|
useUplink(route) {
|
|
1879
2011
|
this.route = route;
|
|
1880
2012
|
}
|
|
2013
|
+
tlsClient;
|
|
1881
2014
|
uplinkFor(host) {
|
|
1882
2015
|
const route = this.route;
|
|
1883
2016
|
if (!route) return void 0;
|
|
@@ -2019,12 +2152,12 @@ function serveSocket(socket, port, onClose) {
|
|
|
2019
2152
|
let writes = Promise.resolve();
|
|
2020
2153
|
let credit = 0;
|
|
2021
2154
|
let granted2;
|
|
2022
|
-
const
|
|
2155
|
+
const send2 = (message3, transfer) => {
|
|
2023
2156
|
if (!closed) port.postMessage(message3, transfer);
|
|
2024
2157
|
};
|
|
2025
2158
|
const close = (reset = false) => {
|
|
2026
2159
|
if (closed) return;
|
|
2027
|
-
if (reset)
|
|
2160
|
+
if (reset) send2({ error: "ECONNRESET" });
|
|
2028
2161
|
closed = true;
|
|
2029
2162
|
granted2?.();
|
|
2030
2163
|
socket.close();
|
|
@@ -2036,9 +2169,9 @@ function serveSocket(socket, port, onClose) {
|
|
|
2036
2169
|
if (closed) return;
|
|
2037
2170
|
try {
|
|
2038
2171
|
await socket.write(data);
|
|
2039
|
-
|
|
2172
|
+
send2({ ack: true });
|
|
2040
2173
|
} catch (err) {
|
|
2041
|
-
|
|
2174
|
+
send2({ error: codeOf(err) });
|
|
2042
2175
|
}
|
|
2043
2176
|
});
|
|
2044
2177
|
};
|
|
@@ -2063,11 +2196,11 @@ function serveSocket(socket, port, onClose) {
|
|
|
2063
2196
|
const chunk2 = await socket.read(CHUNK2);
|
|
2064
2197
|
if (chunk2.length === 0) break;
|
|
2065
2198
|
credit--;
|
|
2066
|
-
|
|
2199
|
+
send2(chunk2, [chunk2.buffer]);
|
|
2067
2200
|
}
|
|
2068
|
-
|
|
2201
|
+
send2({ end: true });
|
|
2069
2202
|
} catch (err) {
|
|
2070
|
-
|
|
2203
|
+
send2({ error: codeOf(err) });
|
|
2071
2204
|
}
|
|
2072
2205
|
})();
|
|
2073
2206
|
return () => close(true);
|
|
@@ -2382,7 +2515,7 @@ function requestBody(request) {
|
|
|
2382
2515
|
return request.body ? { body: request.body } : {};
|
|
2383
2516
|
}
|
|
2384
2517
|
function fetchTransport(options = {}) {
|
|
2385
|
-
const
|
|
2518
|
+
const send2 = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
2386
2519
|
const Socket = options.webSocket === true ? globalThis.WebSocket : options.webSocket || void 0;
|
|
2387
2520
|
const headers = options.webSocketHeaders === true;
|
|
2388
2521
|
const redirect = options.redirect ?? "follow";
|
|
@@ -2399,7 +2532,7 @@ function fetchTransport(options = {}) {
|
|
|
2399
2532
|
async fetch(request) {
|
|
2400
2533
|
let response;
|
|
2401
2534
|
try {
|
|
2402
|
-
response = await
|
|
2535
|
+
response = await send2(request.url, {
|
|
2403
2536
|
method: request.method,
|
|
2404
2537
|
headers: joinHeaders(request.headers),
|
|
2405
2538
|
...requestBody(request),
|
|
@@ -3199,7 +3332,7 @@ function joinable(l, pgid, ours) {
|
|
|
3199
3332
|
if (sid === void 0) throw fsError("ESRCH", `no process group ${pgid}`);
|
|
3200
3333
|
if (!ours(sid)) throw fsError("EPERM", `process group ${pgid} is in another session`);
|
|
3201
3334
|
}
|
|
3202
|
-
function cdpRegistry(
|
|
3335
|
+
function cdpRegistry(send2, gone) {
|
|
3203
3336
|
const registered = /* @__PURE__ */ new Map();
|
|
3204
3337
|
const drop = (id2) => {
|
|
3205
3338
|
registered.get(id2)?.();
|
|
@@ -3208,7 +3341,7 @@ function cdpRegistry(send, gone) {
|
|
|
3208
3341
|
return {
|
|
3209
3342
|
serve(l, req) {
|
|
3210
3343
|
const hook = portCdpHook(
|
|
3211
|
-
(request, cdp) =>
|
|
3344
|
+
(request, cdp) => send2({ cdpOpen: { ...request, registration: req.id }, port: cdp }, [
|
|
3212
3345
|
cdp
|
|
3213
3346
|
]),
|
|
3214
3347
|
gone
|
|
@@ -3222,7 +3355,7 @@ function cdpRegistry(send, gone) {
|
|
|
3222
3355
|
}
|
|
3223
3356
|
};
|
|
3224
3357
|
}
|
|
3225
|
-
function facadeRegistry(
|
|
3358
|
+
function facadeRegistry(send2, gone) {
|
|
3226
3359
|
const registered = /* @__PURE__ */ new Map();
|
|
3227
3360
|
const drop = (id2) => {
|
|
3228
3361
|
registered.get(id2)?.();
|
|
@@ -3231,7 +3364,7 @@ function facadeRegistry(send, gone) {
|
|
|
3231
3364
|
return {
|
|
3232
3365
|
serve(l, req) {
|
|
3233
3366
|
const hook = portFacadeHook(
|
|
3234
|
-
(request, facade) =>
|
|
3367
|
+
(request, facade) => send2({ facadeOpen: { ...request, registration: req.id }, port: facade }, [
|
|
3235
3368
|
facade
|
|
3236
3369
|
]),
|
|
3237
3370
|
gone
|
|
@@ -3245,9 +3378,9 @@ function facadeRegistry(send, gone) {
|
|
|
3245
3378
|
}
|
|
3246
3379
|
};
|
|
3247
3380
|
}
|
|
3248
|
-
function hostRegistries(
|
|
3249
|
-
const cdps = cdpRegistry(
|
|
3250
|
-
const facades = facadeRegistry(
|
|
3381
|
+
function hostRegistries(send2, gone) {
|
|
3382
|
+
const cdps = cdpRegistry(send2, gone);
|
|
3383
|
+
const facades = facadeRegistry(send2, gone);
|
|
3251
3384
|
return {
|
|
3252
3385
|
answer(l, req) {
|
|
3253
3386
|
if (req.op === "serve-cdp") return cdps.serve(l, req);
|
|
@@ -3274,21 +3407,21 @@ function visibleTo(g, notify) {
|
|
|
3274
3407
|
});
|
|
3275
3408
|
};
|
|
3276
3409
|
}
|
|
3277
|
-
async function watchOp(l, req, watches,
|
|
3410
|
+
async function watchOp(l, req, watches, send2, g) {
|
|
3278
3411
|
if (req.op === "unwatch") {
|
|
3279
3412
|
watches.get(req.watch)?.();
|
|
3280
3413
|
watches.delete(req.watch);
|
|
3281
3414
|
return { result: true };
|
|
3282
3415
|
}
|
|
3283
3416
|
if (g) for (const path of req.paths) await readable(g, "watch", l.fs.resolvePath("/", path));
|
|
3284
|
-
const notify = visibleTo(g, (change) =>
|
|
3417
|
+
const notify = visibleTo(g, (change) => send2({ watch: req.id, change }));
|
|
3285
3418
|
const unwatch = l.watchers.watch(req.paths, { recursive: req.recursive }, notify);
|
|
3286
3419
|
watches.set(req.id, unwatch);
|
|
3287
3420
|
return { result: req.id };
|
|
3288
3421
|
}
|
|
3289
3422
|
var TRAITS_WATCH = -1;
|
|
3290
|
-
function traitsWatch(launcher, transport,
|
|
3291
|
-
return launcher.onTraits(() =>
|
|
3423
|
+
function traitsWatch(launcher, transport, send2) {
|
|
3424
|
+
return launcher.onTraits(() => send2({ traits: transport.traits }));
|
|
3292
3425
|
}
|
|
3293
3426
|
function serveClient(port, host) {
|
|
3294
3427
|
let state = "new";
|
|
@@ -3300,14 +3433,14 @@ function serveClient(port, host) {
|
|
|
3300
3433
|
const watches = /* @__PURE__ */ new Map();
|
|
3301
3434
|
let net;
|
|
3302
3435
|
const ended = Promise.withResolvers();
|
|
3303
|
-
const
|
|
3436
|
+
const send2 = (message3, transfer = []) => {
|
|
3304
3437
|
if (state !== "closed") port.postMessage(message3, transfer);
|
|
3305
3438
|
};
|
|
3306
|
-
const reply = (id2, body, transfer) =>
|
|
3307
|
-
const hosts = hostRegistries(
|
|
3439
|
+
const reply = (id2, body, transfer) => send2({ id: id2, ...body }, transfer);
|
|
3440
|
+
const hosts = hostRegistries(send2, ended.promise);
|
|
3308
3441
|
function detach(kill = false, bye = "the slicc-kernel detached this client") {
|
|
3309
3442
|
if (state === "closed") return;
|
|
3310
|
-
|
|
3443
|
+
send2({ bye });
|
|
3311
3444
|
state = "closed";
|
|
3312
3445
|
net?.close();
|
|
3313
3446
|
for (const unwatch of watches.values()) unwatch();
|
|
@@ -3321,19 +3454,19 @@ function serveClient(port, host) {
|
|
|
3321
3454
|
ended.resolve();
|
|
3322
3455
|
}
|
|
3323
3456
|
async function hello(message3) {
|
|
3324
|
-
const
|
|
3325
|
-
if (
|
|
3326
|
-
|
|
3457
|
+
const refused3 = versionError(message3.protocol);
|
|
3458
|
+
if (refused3) {
|
|
3459
|
+
send2({ hello: { protocol: PROTOCOL, error: refused3 } });
|
|
3327
3460
|
detach();
|
|
3328
3461
|
return;
|
|
3329
3462
|
}
|
|
3330
3463
|
const launcher = await host.launcher();
|
|
3331
3464
|
if (host.scope !== "transport") self = await accountOf(launcher, host.user ?? 0);
|
|
3332
3465
|
const transport = host.transport?.() ?? launcher.transport;
|
|
3333
|
-
net = serveTransport({ postMessage: (m, t) =>
|
|
3466
|
+
net = serveTransport({ postMessage: (m, t) => send2(m, t) }, transport);
|
|
3334
3467
|
state = "open";
|
|
3335
3468
|
if (message3.lock && host.locks) void host.locks.request(message3.lock, () => detach());
|
|
3336
|
-
|
|
3469
|
+
send2({
|
|
3337
3470
|
hello: {
|
|
3338
3471
|
protocol: PROTOCOL,
|
|
3339
3472
|
traits: transport.traits,
|
|
@@ -3341,7 +3474,7 @@ function serveClient(port, host) {
|
|
|
3341
3474
|
...host.lock ? { lock: host.lock } : {}
|
|
3342
3475
|
}
|
|
3343
3476
|
});
|
|
3344
|
-
watches.set(TRAITS_WATCH, traitsWatch(launcher, transport,
|
|
3477
|
+
watches.set(TRAITS_WATCH, traitsWatch(launcher, transport, send2));
|
|
3345
3478
|
}
|
|
3346
3479
|
async function terminal(req, l) {
|
|
3347
3480
|
const session = await l.openTerminal(req.argv, {
|
|
@@ -3405,7 +3538,7 @@ function serveClient(port, host) {
|
|
|
3405
3538
|
return clientFs(l, host.tag, self, req);
|
|
3406
3539
|
case "watch":
|
|
3407
3540
|
case "unwatch":
|
|
3408
|
-
return watchOp(l, req, watches,
|
|
3541
|
+
return watchOp(l, req, watches, send2, guard2(l));
|
|
3409
3542
|
case "mount":
|
|
3410
3543
|
return { result: await l.mountAs(clientCred(self), req.spec) };
|
|
3411
3544
|
case "umount":
|
|
@@ -3431,7 +3564,7 @@ function serveClient(port, host) {
|
|
|
3431
3564
|
if (data.hello) {
|
|
3432
3565
|
if (state === "new") {
|
|
3433
3566
|
hello(data.hello).catch((err) => {
|
|
3434
|
-
|
|
3567
|
+
send2({ hello: { protocol: PROTOCOL, error: String(err?.message ?? err) } });
|
|
3435
3568
|
detach();
|
|
3436
3569
|
});
|
|
3437
3570
|
}
|
|
@@ -5646,18 +5779,19 @@ var UnlinkedKeeper = class {
|
|
|
5646
5779
|
const keeper = this;
|
|
5647
5780
|
const { replacing } = this;
|
|
5648
5781
|
const replace = async (target, op) => {
|
|
5649
|
-
const before = replacing.get(target);
|
|
5650
5782
|
const { promise, resolve: resolve2 } = Promise.withResolvers();
|
|
5651
|
-
|
|
5652
|
-
|
|
5783
|
+
let mine;
|
|
5784
|
+
const gated = () => {
|
|
5785
|
+
const before = replacing.get(target);
|
|
5786
|
+
mine = { done: Promise.all([before?.done, promise]).then(() => void 0) };
|
|
5787
|
+
replacing.set(target, mine);
|
|
5653
5788
|
};
|
|
5654
|
-
replacing.set(target, mine);
|
|
5655
5789
|
try {
|
|
5656
|
-
await op();
|
|
5790
|
+
await op(gated);
|
|
5657
5791
|
} finally {
|
|
5658
5792
|
keeper.replaced += 1;
|
|
5659
5793
|
resolve2();
|
|
5660
|
-
if (replacing.get(target) === mine) replacing.delete(target);
|
|
5794
|
+
if (mine && replacing.get(target) === mine) replacing.delete(target);
|
|
5661
5795
|
}
|
|
5662
5796
|
};
|
|
5663
5797
|
const unreplaced = async (path, op) => {
|
|
@@ -5702,8 +5836,8 @@ var UnlinkedKeeper = class {
|
|
|
5702
5836
|
async rename(from, to) {
|
|
5703
5837
|
const target = fs.resolvePath("/", to);
|
|
5704
5838
|
if (target === fs.resolvePath("/", from)) return fs.rename(from, to);
|
|
5705
|
-
await replace(target, async () => {
|
|
5706
|
-
const pinned = await keeper.pin(target);
|
|
5839
|
+
await replace(target, async (gated) => {
|
|
5840
|
+
const pinned = await keeper.pin(target, gated);
|
|
5707
5841
|
await keeper.settle(pinned, () => fs.rename(from, to));
|
|
5708
5842
|
});
|
|
5709
5843
|
},
|
|
@@ -5720,7 +5854,7 @@ var UnlinkedKeeper = class {
|
|
|
5720
5854
|
}
|
|
5721
5855
|
pinned.commit();
|
|
5722
5856
|
}
|
|
5723
|
-
|
|
5857
|
+
heldWithin(target) {
|
|
5724
5858
|
const held = /* @__PURE__ */ new Map();
|
|
5725
5859
|
for (const holder of this.holders) {
|
|
5726
5860
|
if (holder.owns(target)) continue;
|
|
@@ -5729,11 +5863,19 @@ var UnlinkedKeeper = class {
|
|
|
5729
5863
|
held.set(path, [...held.get(path) ?? [], holder]);
|
|
5730
5864
|
}
|
|
5731
5865
|
}
|
|
5732
|
-
|
|
5866
|
+
return held;
|
|
5867
|
+
}
|
|
5868
|
+
async pin(target, gated = () => void 0) {
|
|
5869
|
+
const paths = [...this.heldWithin(target).keys()].sort();
|
|
5733
5870
|
const releases = [];
|
|
5734
5871
|
for (const path of paths) releases.push(await this.gate.acquire(path));
|
|
5872
|
+
gated();
|
|
5873
|
+
const now = this.heldWithin(target);
|
|
5874
|
+
const held = new Map(
|
|
5875
|
+
paths.flatMap((path) => now.has(path) ? [[path, now.get(path)]] : [])
|
|
5876
|
+
);
|
|
5735
5877
|
const hidden = /* @__PURE__ */ new Map();
|
|
5736
|
-
for (const path of
|
|
5878
|
+
for (const path of held.keys()) {
|
|
5737
5879
|
const at = await this.hide(path);
|
|
5738
5880
|
if (at !== void 0) hidden.set(path, at);
|
|
5739
5881
|
}
|
|
@@ -6802,7 +6944,7 @@ function satisfies(version, range2) {
|
|
|
6802
6944
|
}
|
|
6803
6945
|
|
|
6804
6946
|
// src/version.ts
|
|
6805
|
-
var KERNEL_VERSION = true ? "1.
|
|
6947
|
+
var KERNEL_VERSION = true ? "1.124.1" : "0.0.0-dev";
|
|
6806
6948
|
var OS_RELEASE = "6.0.0-slicc";
|
|
6807
6949
|
function procVersion() {
|
|
6808
6950
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -7084,13 +7226,13 @@ async function tierPackages(fs, physical, roots, bins, kernel) {
|
|
|
7084
7226
|
const own = commandsOf(pkg, manifest);
|
|
7085
7227
|
const named = new Set(own.map((command) => command.name));
|
|
7086
7228
|
const extra = bins ? await binCommandsOf(physical, pkg, manifest, named) : [];
|
|
7087
|
-
const
|
|
7229
|
+
const refused3 = engineRefusal(manifest, kernel);
|
|
7088
7230
|
const commands = [...own, ...extra];
|
|
7089
7231
|
out.push({
|
|
7090
7232
|
name: pkg.slice(root.length + 1),
|
|
7091
7233
|
pkg,
|
|
7092
7234
|
replaces: replacesOf(manifest),
|
|
7093
|
-
commands:
|
|
7235
|
+
commands: refused3 ? commands.map((command) => ({ ...command, refused: refused3 })) : commands
|
|
7094
7236
|
});
|
|
7095
7237
|
}
|
|
7096
7238
|
}
|
|
@@ -8400,8 +8542,8 @@ var RealmProxy = class {
|
|
|
8400
8542
|
}
|
|
8401
8543
|
async connect(conn, incoming, req, idle) {
|
|
8402
8544
|
const target = tunnelTarget(req);
|
|
8403
|
-
const
|
|
8404
|
-
if (
|
|
8545
|
+
const refused3 = target.port === 443 ? await this.tunnelReady(target) : void 0;
|
|
8546
|
+
if (refused3) throw refused3;
|
|
8405
8547
|
await conn.write(latin1Bytes("HTTP/1.1 200 Connection Established\r\n\r\n"), this.stop.signal);
|
|
8406
8548
|
try {
|
|
8407
8549
|
const first = await incoming.peek(this.stop.signal);
|
|
@@ -10055,8 +10197,8 @@ var DriverConnection = class _DriverConnection {
|
|
|
10055
10197
|
} finally {
|
|
10056
10198
|
clearTimeout(timer);
|
|
10057
10199
|
}
|
|
10058
|
-
const
|
|
10059
|
-
if (
|
|
10200
|
+
const refused3 = driverVersionError(hello.protocol);
|
|
10201
|
+
if (refused3) throw errnoError("EPROTO", refused3);
|
|
10060
10202
|
if (hello.error) throw errnoError(hello.errno ?? "EIO", hello.error);
|
|
10061
10203
|
return new _DriverConnection(port, hello.capabilities ?? {}, waiting, timeoutMs, options);
|
|
10062
10204
|
}
|
|
@@ -11878,8 +12020,8 @@ async function guarded(entry, path, req) {
|
|
|
11878
12020
|
return { paths };
|
|
11879
12021
|
} catch (err) {
|
|
11880
12022
|
const refusal2 = err.code === "EACCES";
|
|
11881
|
-
const
|
|
11882
|
-
return { refused:
|
|
12023
|
+
const refused3 = req.op === "exists" && refusal2 ? json2(false) : toErrno(err);
|
|
12024
|
+
return { refused: refused3 };
|
|
11883
12025
|
}
|
|
11884
12026
|
}
|
|
11885
12027
|
async function createExclusive(fs, path, owner) {
|
|
@@ -11990,13 +12132,13 @@ async function dispatchSyncFs(req) {
|
|
|
11990
12132
|
}
|
|
11991
12133
|
}
|
|
11992
12134
|
var DENIED = /* @__PURE__ */ new Set(["EACCES", "EPERM"]);
|
|
11993
|
-
async function rmPermitted(entry, path, req,
|
|
12135
|
+
async function rmPermitted(entry, path, req, refused3) {
|
|
11994
12136
|
const st = await entry.fs.lstat(path).catch(() => void 0);
|
|
11995
|
-
if (!st?.isDirectory) return
|
|
12137
|
+
if (!st?.isDirectory) return refused3;
|
|
11996
12138
|
const unlisted = await guarded(entry, path, { ...req, op: "readdir" });
|
|
11997
12139
|
if ("refused" in unlisted) return unlisted.refused;
|
|
11998
12140
|
const names = await entry.fs.readdir(path).catch(() => void 0);
|
|
11999
|
-
if (!names) return
|
|
12141
|
+
if (!names) return refused3;
|
|
12000
12142
|
let first;
|
|
12001
12143
|
for (const name2 of names) {
|
|
12002
12144
|
const child = await dispatchOne(entry, {
|
|
@@ -12047,14 +12189,14 @@ async function newDevName(entry, path, req) {
|
|
|
12047
12189
|
const named = NAMING.has(req.op);
|
|
12048
12190
|
if (!named && !CREATIONS.has(req.op)) return void 0;
|
|
12049
12191
|
const target = named ? entry.fs.resolvePath(entry.cwd, req.arg2 ?? "") : path;
|
|
12050
|
-
const
|
|
12051
|
-
if (!
|
|
12192
|
+
const refused3 = devCreation(target, entry.cred?.());
|
|
12193
|
+
if (!refused3) return void 0;
|
|
12052
12194
|
const there = await entry.fs.lstat(target).then(
|
|
12053
12195
|
() => true,
|
|
12054
12196
|
() => false
|
|
12055
12197
|
);
|
|
12056
12198
|
if (there) return void 0;
|
|
12057
|
-
return { ok: false, errno:
|
|
12199
|
+
return { ok: false, errno: refused3, message: `${target}: no new names in /dev or /proc` };
|
|
12058
12200
|
}
|
|
12059
12201
|
async function dispatchOne(entry, req) {
|
|
12060
12202
|
const { fs, cwd } = entry;
|
|
@@ -13457,6 +13599,9 @@ var FlockTable = class {
|
|
|
13457
13599
|
held = /* @__PURE__ */ new Map();
|
|
13458
13600
|
keys = /* @__PURE__ */ new WeakMap();
|
|
13459
13601
|
wakers = /* @__PURE__ */ new Map();
|
|
13602
|
+
isFree(key, owner, kind) {
|
|
13603
|
+
return this.free(key, owner, kind);
|
|
13604
|
+
}
|
|
13460
13605
|
free(key, owner, kind) {
|
|
13461
13606
|
for (const [other, has] of this.held.get(key) ?? [])
|
|
13462
13607
|
if (other !== owner && (kind === "exclusive" || has === "exclusive")) return false;
|
|
@@ -13583,9 +13728,18 @@ var LockTable = class {
|
|
|
13583
13728
|
);
|
|
13584
13729
|
this.wake(key);
|
|
13585
13730
|
}
|
|
13731
|
+
wholeFree(pid, path, exclusive) {
|
|
13732
|
+
for (const [other, h] of this.held.get(path) ?? []) {
|
|
13733
|
+
if (other !== pid && (exclusive || h.exclusive)) return false;
|
|
13734
|
+
}
|
|
13735
|
+
return true;
|
|
13736
|
+
}
|
|
13737
|
+
flockFree(key, owner, kind) {
|
|
13738
|
+
return this.flocks.isFree(key, owner, kind);
|
|
13739
|
+
}
|
|
13586
13740
|
lock(pid, path, exclusive, fd) {
|
|
13741
|
+
if (!this.wholeFree(pid, path, exclusive)) return false;
|
|
13587
13742
|
const holders = this.held.get(path) ?? /* @__PURE__ */ new Map();
|
|
13588
|
-
for (const [other, h] of holders) if (other !== pid && (exclusive || h.exclusive)) return false;
|
|
13589
13743
|
const mine = holders.get(pid) ?? { exclusive, fds: /* @__PURE__ */ new Set() };
|
|
13590
13744
|
mine.exclusive = exclusive;
|
|
13591
13745
|
mine.fds.add(fd);
|
|
@@ -13770,12 +13924,12 @@ var AsyncOps = class {
|
|
|
13770
13924
|
async function hostSyscall(req, ctx) {
|
|
13771
13925
|
switch (req.op) {
|
|
13772
13926
|
case "lock":
|
|
13773
|
-
|
|
13774
|
-
if (!ctx.locks.lock(ctx.pid, req.path, req.exclusive, req.fd))
|
|
13775
|
-
throw new KernelError("EAGAIN");
|
|
13776
|
-
return done2;
|
|
13927
|
+
return wholeLock(req, ctx);
|
|
13777
13928
|
case "unlock":
|
|
13778
13929
|
ctx.locks?.unlock(ctx.pid, req.path);
|
|
13930
|
+
if (req.fd !== void 0 && ctx.locks?.shared?.() && ctx.flockOf) {
|
|
13931
|
+
return flock({ op: "flock", fd: req.fd, kind: "unlock" }, ctx);
|
|
13932
|
+
}
|
|
13779
13933
|
return done2;
|
|
13780
13934
|
case "lk-set":
|
|
13781
13935
|
case "lk-get":
|
|
@@ -13805,6 +13959,23 @@ async function hostSyscall(req, ctx) {
|
|
|
13805
13959
|
return done2;
|
|
13806
13960
|
}
|
|
13807
13961
|
}
|
|
13962
|
+
async function wholeLock(req, ctx) {
|
|
13963
|
+
const { locks, flockOf } = ctx;
|
|
13964
|
+
if (!locks) throw new KernelError("ENOSYS");
|
|
13965
|
+
const kind = req.exclusive ? "exclusive" : "shared";
|
|
13966
|
+
if (locks.shared?.() && flockOf) {
|
|
13967
|
+
if (locks.wholeFree?.(ctx.pid, req.path, req.exclusive) === false) {
|
|
13968
|
+
throw new KernelError("EAGAIN");
|
|
13969
|
+
}
|
|
13970
|
+
return flock({ op: "flock", fd: req.fd, kind }, ctx);
|
|
13971
|
+
}
|
|
13972
|
+
if (flockOf && locks.flockFree) {
|
|
13973
|
+
const { key, owner } = await flockOf(req.fd);
|
|
13974
|
+
if (!locks.flockFree(key, owner, kind)) throw new KernelError("EAGAIN");
|
|
13975
|
+
}
|
|
13976
|
+
if (!locks.lock(ctx.pid, req.path, req.exclusive, req.fd)) throw new KernelError("EAGAIN");
|
|
13977
|
+
return done2;
|
|
13978
|
+
}
|
|
13808
13979
|
var FLOCK_KINDS = /* @__PURE__ */ new Set(["shared", "exclusive", "unlock"]);
|
|
13809
13980
|
async function flock(req, ctx) {
|
|
13810
13981
|
const { locks, flockOf } = ctx;
|
|
@@ -13991,8 +14162,8 @@ var KernelLoopback = class {
|
|
|
13991
14162
|
);
|
|
13992
14163
|
} catch (err) {
|
|
13993
14164
|
socket.close();
|
|
13994
|
-
const
|
|
13995
|
-
throw
|
|
14165
|
+
const refused3 = err instanceof KernelError && err.code === "ECONNREFUSED";
|
|
14166
|
+
throw refused3 ? errno2("ECONNREFUSED", `nothing listens on the kernel's port ${port}`) : err;
|
|
13996
14167
|
}
|
|
13997
14168
|
signal.addEventListener("abort", () => socket.close(), { once: true });
|
|
13998
14169
|
return socket;
|
|
@@ -14484,6 +14655,7 @@ function realmCa(owner, store) {
|
|
|
14484
14655
|
}
|
|
14485
14656
|
|
|
14486
14657
|
// src/kernel/net/tls-engine.ts
|
|
14658
|
+
var TLS_CLIENT_INSECURE_SKIP_VERIFY = 1;
|
|
14487
14659
|
var SCRATCH = 64 * 1024;
|
|
14488
14660
|
var EOF = -1;
|
|
14489
14661
|
var TlsError = class extends Error {
|
|
@@ -14544,6 +14716,76 @@ var TlsEngine = class {
|
|
|
14544
14716
|
const n = fn(this.scratch, SCRATCH);
|
|
14545
14717
|
return n > 0 ? this.taken(n) : n;
|
|
14546
14718
|
}
|
|
14719
|
+
get client() {
|
|
14720
|
+
return typeof this.m._tls_client_new === "function" ? this.m : void 0;
|
|
14721
|
+
}
|
|
14722
|
+
clientModule() {
|
|
14723
|
+
const m = this.client;
|
|
14724
|
+
if (!m) throw new TlsError(0, "tls client: the installed tls engine has no client sessions");
|
|
14725
|
+
return m;
|
|
14726
|
+
}
|
|
14727
|
+
store() {
|
|
14728
|
+
const m = this.clientModule();
|
|
14729
|
+
const ptr = m._tls_ca_new();
|
|
14730
|
+
if (!ptr) throw this.error(m._tls_last_error(), "trust store");
|
|
14731
|
+
return new TlsStore(this, m, ptr);
|
|
14732
|
+
}
|
|
14733
|
+
clientSession(store, servername, alpn, flags2) {
|
|
14734
|
+
const m = this.clientModule();
|
|
14735
|
+
const wire = alpnWire(alpn);
|
|
14736
|
+
const name2 = this.put(new TextEncoder().encode(servername));
|
|
14737
|
+
try {
|
|
14738
|
+
const at = store?.ptr ?? 0;
|
|
14739
|
+
const ptr = this.withBytes(wire, (p) => m._tls_client_new(at, name2, p, wire.length, flags2));
|
|
14740
|
+
if (!ptr) throw this.error(m._tls_last_error(), "tls client");
|
|
14741
|
+
return new TlsSession(this, m, ptr);
|
|
14742
|
+
} finally {
|
|
14743
|
+
this.m._free(name2);
|
|
14744
|
+
}
|
|
14745
|
+
}
|
|
14746
|
+
verifyInfo(flags2) {
|
|
14747
|
+
const m = this.clientModule();
|
|
14748
|
+
const n = m._tls_verify_info(flags2, this.scratch, SCRATCH);
|
|
14749
|
+
const end = this.m.HEAPU8.indexOf(0, this.scratch);
|
|
14750
|
+
const text = new TextDecoder().decode(this.m.HEAPU8.subarray(this.scratch, end));
|
|
14751
|
+
return n < 0 ? `${text}\u2026` : text;
|
|
14752
|
+
}
|
|
14753
|
+
};
|
|
14754
|
+
function alpnWire(names) {
|
|
14755
|
+
const parts2 = names.map((name2) => new TextEncoder().encode(name2));
|
|
14756
|
+
const out = new Uint8Array(parts2.reduce((n, p) => n + p.length + 1, 0));
|
|
14757
|
+
let at = 0;
|
|
14758
|
+
for (const part of parts2) {
|
|
14759
|
+
out[at++] = part.length;
|
|
14760
|
+
out.set(part, at);
|
|
14761
|
+
at += part.length;
|
|
14762
|
+
}
|
|
14763
|
+
return out;
|
|
14764
|
+
}
|
|
14765
|
+
var TlsStore = class {
|
|
14766
|
+
engine;
|
|
14767
|
+
m;
|
|
14768
|
+
ptr;
|
|
14769
|
+
constructor(engine, m, ptr) {
|
|
14770
|
+
this.engine = engine;
|
|
14771
|
+
this.m = m;
|
|
14772
|
+
this.ptr = ptr;
|
|
14773
|
+
}
|
|
14774
|
+
add(der) {
|
|
14775
|
+
const ret = this.engine.withBytes(der, (p) => this.m._tls_ca_add_der(this.ptr, p, der.length));
|
|
14776
|
+
if (ret !== 0) throw this.engine.error(ret, "trust store certificate");
|
|
14777
|
+
}
|
|
14778
|
+
addBundle(bytes) {
|
|
14779
|
+
const n = this.engine.withBytes(
|
|
14780
|
+
bytes,
|
|
14781
|
+
(p) => this.m._tls_ca_add_bundle(this.ptr, p, bytes.length)
|
|
14782
|
+
);
|
|
14783
|
+
if (n < 0) throw this.engine.error(n, "trust store bundle");
|
|
14784
|
+
return n;
|
|
14785
|
+
}
|
|
14786
|
+
release() {
|
|
14787
|
+
this.m._tls_ca_free(this.ptr);
|
|
14788
|
+
}
|
|
14547
14789
|
};
|
|
14548
14790
|
var TlsLeaf = class {
|
|
14549
14791
|
engine;
|
|
@@ -14608,6 +14850,33 @@ var TlsSession = class {
|
|
|
14608
14850
|
free() {
|
|
14609
14851
|
this.m._tls_session_free(this.ptr);
|
|
14610
14852
|
}
|
|
14853
|
+
get c() {
|
|
14854
|
+
return this.m;
|
|
14855
|
+
}
|
|
14856
|
+
handshake() {
|
|
14857
|
+
const ret = this.c._tls_handshake(this.ptr);
|
|
14858
|
+
if (ret < 0) throw this.engine.error(ret, "tls handshake");
|
|
14859
|
+
return ret === 1;
|
|
14860
|
+
}
|
|
14861
|
+
get verifyResult() {
|
|
14862
|
+
return this.c._tls_verify_result(this.ptr);
|
|
14863
|
+
}
|
|
14864
|
+
get version() {
|
|
14865
|
+
return this.c._tls_version(this.ptr);
|
|
14866
|
+
}
|
|
14867
|
+
get alpn() {
|
|
14868
|
+
const out = this.engine.intoScratch((p, max) => this.c._tls_alpn(this.ptr, p, max));
|
|
14869
|
+
return out instanceof Uint8Array ? new TextDecoder().decode(out) : void 0;
|
|
14870
|
+
}
|
|
14871
|
+
peerChain() {
|
|
14872
|
+
const chain2 = [];
|
|
14873
|
+
const count2 = this.c._tls_peer_count(this.ptr);
|
|
14874
|
+
for (let i = 0; i < count2; i++) {
|
|
14875
|
+
const der = this.engine.intoScratch((p, max) => this.c._tls_peer_der(this.ptr, i, p, max));
|
|
14876
|
+
if (der instanceof Uint8Array) chain2.push(der);
|
|
14877
|
+
}
|
|
14878
|
+
return chain2;
|
|
14879
|
+
}
|
|
14611
14880
|
};
|
|
14612
14881
|
var loading = /* @__PURE__ */ new WeakMap();
|
|
14613
14882
|
function loadTlsEngine(load) {
|
|
@@ -14816,6 +15085,16 @@ function packageTlsEngine(fs, modules) {
|
|
|
14816
15085
|
return factory.default({ wasmBinary, locateFile: (path) => path });
|
|
14817
15086
|
};
|
|
14818
15087
|
}
|
|
15088
|
+
function packageTlsRoots(fs, modules) {
|
|
15089
|
+
const file = `${modules.replace(/\/+$/, "")}/${TLS_ENGINE_PACKAGE}/dist/roots.der`;
|
|
15090
|
+
return async () => {
|
|
15091
|
+
try {
|
|
15092
|
+
return await fs.readFileBuffer(file);
|
|
15093
|
+
} catch {
|
|
15094
|
+
throw new Error(`TLS client sessions need ${TLS_ENGINE_PACKAGE}'s roots.der in ${modules}`);
|
|
15095
|
+
}
|
|
15096
|
+
};
|
|
15097
|
+
}
|
|
14819
15098
|
function kernelCa(store) {
|
|
14820
15099
|
return () => realmCa(CA_OWNER, store);
|
|
14821
15100
|
}
|
|
@@ -14847,6 +15126,7 @@ async function writeCaFile(fs, ca, locks = globalThis.navigator?.locks) {
|
|
|
14847
15126
|
function enableNetwork(net, options) {
|
|
14848
15127
|
let proxy;
|
|
14849
15128
|
const transport = options.transport ?? missingTransport();
|
|
15129
|
+
if (options.roots) net.tlsClient = { engine: options.engine, roots: options.roots };
|
|
14850
15130
|
const start2 = () => {
|
|
14851
15131
|
const tls2 = new TlsTerminator({
|
|
14852
15132
|
ca: options.ca,
|
|
@@ -16516,6 +16796,285 @@ function encodeReceived(got) {
|
|
|
16516
16796
|
return out;
|
|
16517
16797
|
}
|
|
16518
16798
|
|
|
16799
|
+
// src/kernel/net/tls-client.ts
|
|
16800
|
+
var WRITE_CHUNK = 16 * 1024;
|
|
16801
|
+
var BADCERT = [
|
|
16802
|
+
[8, "UNABLE_TO_GET_ISSUER_CERT_LOCALLY"],
|
|
16803
|
+
[1, "CERT_HAS_EXPIRED"],
|
|
16804
|
+
[512, "CERT_NOT_YET_VALID"],
|
|
16805
|
+
[2, "CERT_REVOKED"],
|
|
16806
|
+
[4, "ERR_TLS_CERT_ALTNAME_INVALID"],
|
|
16807
|
+
[2048, "INVALID_PURPOSE"],
|
|
16808
|
+
[4096, "INVALID_PURPOSE"]
|
|
16809
|
+
];
|
|
16810
|
+
function verifyCode(flags2) {
|
|
16811
|
+
if (flags2 === 0) return void 0;
|
|
16812
|
+
if (flags2 === -1) return "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
|
|
16813
|
+
return BADCERT.find(([bit]) => (flags2 & bit) !== 0)?.[1] ?? "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
|
|
16814
|
+
}
|
|
16815
|
+
var Ciphertext = class {
|
|
16816
|
+
queue = [];
|
|
16817
|
+
ended = false;
|
|
16818
|
+
conn;
|
|
16819
|
+
session;
|
|
16820
|
+
constructor(conn, session) {
|
|
16821
|
+
this.conn = conn;
|
|
16822
|
+
this.session = session;
|
|
16823
|
+
}
|
|
16824
|
+
hand(bytes) {
|
|
16825
|
+
if (bytes.length > 0) this.queue.push(bytes);
|
|
16826
|
+
}
|
|
16827
|
+
async more() {
|
|
16828
|
+
if (this.queue.length === 0 && !this.ended) {
|
|
16829
|
+
const bytes = await this.conn.read();
|
|
16830
|
+
if (bytes) this.queue.push(bytes);
|
|
16831
|
+
else this.ended = true;
|
|
16832
|
+
}
|
|
16833
|
+
if (this.queue.length === 0) {
|
|
16834
|
+
this.session.feedEnd();
|
|
16835
|
+
return false;
|
|
16836
|
+
}
|
|
16837
|
+
while (this.queue.length > 0) {
|
|
16838
|
+
const head = this.queue[0];
|
|
16839
|
+
const n = this.session.feed(head);
|
|
16840
|
+
if (n < head.length) {
|
|
16841
|
+
this.queue[0] = head.subarray(n);
|
|
16842
|
+
break;
|
|
16843
|
+
}
|
|
16844
|
+
this.queue.shift();
|
|
16845
|
+
}
|
|
16846
|
+
return true;
|
|
16847
|
+
}
|
|
16848
|
+
};
|
|
16849
|
+
async function send(conn, session) {
|
|
16850
|
+
for (; ; ) {
|
|
16851
|
+
const out = session.take();
|
|
16852
|
+
if (out.length === 0) return;
|
|
16853
|
+
for (let at = 0; at < out.length; ) {
|
|
16854
|
+
const n = await conn.write(out.subarray(at));
|
|
16855
|
+
if (!(n > 0)) throw new KernelError("EPIPE");
|
|
16856
|
+
at += n;
|
|
16857
|
+
}
|
|
16858
|
+
}
|
|
16859
|
+
}
|
|
16860
|
+
function refused2(engine, session, err) {
|
|
16861
|
+
const flags2 = session.verifyResult;
|
|
16862
|
+
const code = verifyCode(flags2);
|
|
16863
|
+
if (code && flags2 !== -1)
|
|
16864
|
+
return new KernelError("EPROTO", `${code}: ${engine.verifyInfo(flags2).trim()}`);
|
|
16865
|
+
const text = err instanceof TlsError ? err.message : String(err);
|
|
16866
|
+
return new KernelError("EPROTO", `ERR_SSL_HANDSHAKE_FAILURE: ${text}`);
|
|
16867
|
+
}
|
|
16868
|
+
async function handshake(conn, o, session, inbox) {
|
|
16869
|
+
for (; ; ) {
|
|
16870
|
+
let done4;
|
|
16871
|
+
try {
|
|
16872
|
+
done4 = session.handshake();
|
|
16873
|
+
} catch (err) {
|
|
16874
|
+
await send(conn, session).catch(() => void 0);
|
|
16875
|
+
throw refused2(o.engine, session, err);
|
|
16876
|
+
}
|
|
16877
|
+
await send(conn, session);
|
|
16878
|
+
if (done4) return;
|
|
16879
|
+
if (!await inbox.more()) {
|
|
16880
|
+
throw new KernelError(
|
|
16881
|
+
"ECONNRESET",
|
|
16882
|
+
"the server closed the connection during the TLS handshake"
|
|
16883
|
+
);
|
|
16884
|
+
}
|
|
16885
|
+
}
|
|
16886
|
+
}
|
|
16887
|
+
function infoOf(o, session) {
|
|
16888
|
+
const flags2 = session.verifyResult;
|
|
16889
|
+
const code = verifyCode(flags2);
|
|
16890
|
+
return {
|
|
16891
|
+
protocol: session.version === 772 ? "TLSv1.3" : "TLSv1.2",
|
|
16892
|
+
alpnProtocol: session.alpn ?? false,
|
|
16893
|
+
authorized: code === void 0,
|
|
16894
|
+
...code ? { authorizationError: code, authorizationText: o.engine.verifyInfo(flags2).trim() } : {},
|
|
16895
|
+
peerCertificates: session.peerChain()
|
|
16896
|
+
};
|
|
16897
|
+
}
|
|
16898
|
+
function plaintext(conn, session, inbox) {
|
|
16899
|
+
let freed = false;
|
|
16900
|
+
let writeClosed = false;
|
|
16901
|
+
const free = () => {
|
|
16902
|
+
if (freed) return;
|
|
16903
|
+
freed = true;
|
|
16904
|
+
session.free();
|
|
16905
|
+
};
|
|
16906
|
+
return {
|
|
16907
|
+
localAddr: conn.localAddr,
|
|
16908
|
+
remoteAddr: conn.remoteAddr,
|
|
16909
|
+
async read() {
|
|
16910
|
+
for (; ; ) {
|
|
16911
|
+
if (freed) return null;
|
|
16912
|
+
const got = session.read();
|
|
16913
|
+
await send(conn, session);
|
|
16914
|
+
if (got instanceof Uint8Array) return got;
|
|
16915
|
+
if (got === "eof") return null;
|
|
16916
|
+
await inbox.more();
|
|
16917
|
+
}
|
|
16918
|
+
},
|
|
16919
|
+
async write(bytes) {
|
|
16920
|
+
if (freed) throw new KernelError("EPIPE");
|
|
16921
|
+
for (; ; ) {
|
|
16922
|
+
const n = session.write(bytes.subarray(0, WRITE_CHUNK));
|
|
16923
|
+
await send(conn, session);
|
|
16924
|
+
if (n > 0) return n;
|
|
16925
|
+
}
|
|
16926
|
+
},
|
|
16927
|
+
closeWrite() {
|
|
16928
|
+
if (writeClosed || freed) return;
|
|
16929
|
+
writeClosed = true;
|
|
16930
|
+
session.close();
|
|
16931
|
+
void send(conn, session).catch(() => void 0).finally(() => conn.closeWrite());
|
|
16932
|
+
},
|
|
16933
|
+
close() {
|
|
16934
|
+
free();
|
|
16935
|
+
conn.close();
|
|
16936
|
+
}
|
|
16937
|
+
};
|
|
16938
|
+
}
|
|
16939
|
+
async function tlsClient(conn, o, taken = new Uint8Array(0)) {
|
|
16940
|
+
const flags2 = o.insecure ? TLS_CLIENT_INSECURE_SKIP_VERIFY : 0;
|
|
16941
|
+
const session = o.engine.clientSession(o.store, o.servername, o.alpn, flags2);
|
|
16942
|
+
const inbox = new Ciphertext(conn, session);
|
|
16943
|
+
inbox.hand(taken);
|
|
16944
|
+
try {
|
|
16945
|
+
await handshake(conn, o, session, inbox);
|
|
16946
|
+
return { conn: plaintext(conn, session, inbox), info: infoOf(o, session) };
|
|
16947
|
+
} catch (err) {
|
|
16948
|
+
session.free();
|
|
16949
|
+
throw err;
|
|
16950
|
+
}
|
|
16951
|
+
}
|
|
16952
|
+
|
|
16953
|
+
// src/kernel/net/tls-uplink.ts
|
|
16954
|
+
var isIP = (text) => ipv4Bytes(text) !== void 0 || text.includes(":") && ipv6Groups(text) !== void 0;
|
|
16955
|
+
var LABEL2 = /^(?!-)[A-Za-z0-9-]{1,63}(?<!-)$/;
|
|
16956
|
+
function serverName(name2) {
|
|
16957
|
+
if (isIP(name2.replace(/^\[|\]$/g, ""))) return name2.replace(/^\[|\]$/g, "");
|
|
16958
|
+
const bare = name2.endsWith(".") ? name2.slice(0, -1) : name2;
|
|
16959
|
+
if (bare.length === 0 || bare.length > 253 || !bare.split(".").every((l) => LABEL2.test(l))) {
|
|
16960
|
+
throw new KernelError(
|
|
16961
|
+
"EINVAL",
|
|
16962
|
+
`ERR_INVALID_ARG_VALUE: not a host name: ${JSON.stringify(name2)}`
|
|
16963
|
+
);
|
|
16964
|
+
}
|
|
16965
|
+
return name2;
|
|
16966
|
+
}
|
|
16967
|
+
var defaults = /* @__PURE__ */ new WeakMap();
|
|
16968
|
+
function defaultStore(engine, roots) {
|
|
16969
|
+
let store = defaults.get(engine);
|
|
16970
|
+
if (!store) {
|
|
16971
|
+
const made2 = roots().then((bundle) => {
|
|
16972
|
+
const s = engine.store();
|
|
16973
|
+
s.addBundle(bundle);
|
|
16974
|
+
return s;
|
|
16975
|
+
});
|
|
16976
|
+
store = made2;
|
|
16977
|
+
defaults.set(engine, made2);
|
|
16978
|
+
made2.catch(() => {
|
|
16979
|
+
if (defaults.get(engine) === made2) defaults.delete(engine);
|
|
16980
|
+
});
|
|
16981
|
+
}
|
|
16982
|
+
return store;
|
|
16983
|
+
}
|
|
16984
|
+
function base64Der(text) {
|
|
16985
|
+
const bin = atob(text);
|
|
16986
|
+
const out = new Uint8Array(bin.length);
|
|
16987
|
+
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
16988
|
+
return out;
|
|
16989
|
+
}
|
|
16990
|
+
function encode(bytes) {
|
|
16991
|
+
let bin = "";
|
|
16992
|
+
for (const b of bytes) bin += String.fromCharCode(b);
|
|
16993
|
+
return btoa(bin);
|
|
16994
|
+
}
|
|
16995
|
+
function sessionOf(info, servername) {
|
|
16996
|
+
return {
|
|
16997
|
+
path: "kernel",
|
|
16998
|
+
substitutes: false,
|
|
16999
|
+
protocol: info.protocol,
|
|
17000
|
+
alpnProtocol: info.alpnProtocol,
|
|
17001
|
+
authorized: info.authorized,
|
|
17002
|
+
...info.authorizationError ? {
|
|
17003
|
+
authorizationError: info.authorizationError,
|
|
17004
|
+
authorizationText: info.authorizationText
|
|
17005
|
+
} : {},
|
|
17006
|
+
servername,
|
|
17007
|
+
peerCertificates: info.peerCertificates.map(encode)
|
|
17008
|
+
};
|
|
17009
|
+
}
|
|
17010
|
+
async function setUp(support, req) {
|
|
17011
|
+
const engine = await support.engine();
|
|
17012
|
+
if (!engine.client)
|
|
17013
|
+
throw new KernelError("ENOTSUP", "the installed tls engine has no client sessions");
|
|
17014
|
+
const custom = Array.isArray(req.ca) ? req.ca : void 0;
|
|
17015
|
+
if (!custom) return { engine, store: await defaultStore(engine, support.roots), own: void 0 };
|
|
17016
|
+
if (custom.length === 0)
|
|
17017
|
+
throw new KernelError("EINVAL", "ERR_INVALID_ARG_VALUE: ca has no certificate");
|
|
17018
|
+
const own = engine.store();
|
|
17019
|
+
try {
|
|
17020
|
+
for (const der of custom) own.add(base64Der(der));
|
|
17021
|
+
} catch (err) {
|
|
17022
|
+
own.release();
|
|
17023
|
+
throw new KernelError("EINVAL", `ERR_INVALID_ARG_VALUE: ca: ${err.message}`);
|
|
17024
|
+
}
|
|
17025
|
+
return { engine, store: own, own };
|
|
17026
|
+
}
|
|
17027
|
+
function secure(support, req, servername) {
|
|
17028
|
+
return async (raw) => {
|
|
17029
|
+
const { engine, store, own } = await setUp(support, req);
|
|
17030
|
+
try {
|
|
17031
|
+
return await tlsClient(raw, {
|
|
17032
|
+
engine,
|
|
17033
|
+
store,
|
|
17034
|
+
servername,
|
|
17035
|
+
alpn: req.alpn ?? [],
|
|
17036
|
+
insecure: req.insecure === true
|
|
17037
|
+
});
|
|
17038
|
+
} finally {
|
|
17039
|
+
own?.release();
|
|
17040
|
+
}
|
|
17041
|
+
};
|
|
17042
|
+
}
|
|
17043
|
+
function supportOf(net) {
|
|
17044
|
+
const support = net.tlsClient;
|
|
17045
|
+
if (!support) throw new KernelError("ENOTSUP", "no tls engine for client sessions");
|
|
17046
|
+
return support;
|
|
17047
|
+
}
|
|
17048
|
+
async function uplinkAddress(proc, host) {
|
|
17049
|
+
const bare = host.replace(/^\[|\]$/g, "");
|
|
17050
|
+
if (isIP(bare)) return bare;
|
|
17051
|
+
const [first] = await proc.resolve(host, 0, () => proc.blocking());
|
|
17052
|
+
if (!first) throw new KernelError("ENOENT", `ENOTFOUND: ${host}`);
|
|
17053
|
+
return first;
|
|
17054
|
+
}
|
|
17055
|
+
async function connectSecure(proc, socket, host, port, req) {
|
|
17056
|
+
const servername = serverName(req.servername || host);
|
|
17057
|
+
if (isLoopbackHost(servername) || isLoopbackHost(host)) throw new KernelError("ENOTSUP");
|
|
17058
|
+
const address = await uplinkAddress(proc, host);
|
|
17059
|
+
const route = proc.net.uplinkFor(address);
|
|
17060
|
+
if (!route)
|
|
17061
|
+
throw new KernelError("ENOTSUP", "TLS in the kernel needs a destination the uplink routes");
|
|
17062
|
+
const support = supportOf(proc.net);
|
|
17063
|
+
let info;
|
|
17064
|
+
const make = secure(support, req, servername);
|
|
17065
|
+
await socket.connectSecure({ family: "inet", host: address, port }, route, async (conn) => {
|
|
17066
|
+
info = await conn.upgrade(make);
|
|
17067
|
+
});
|
|
17068
|
+
return sessionOf(info, servername);
|
|
17069
|
+
}
|
|
17070
|
+
async function upgradeSecure(proc, socket, req) {
|
|
17071
|
+
const peer = socket.peer;
|
|
17072
|
+
const host = req.servername || (peer?.family === "inet" ? peer.host : "");
|
|
17073
|
+
const servername = serverName(host);
|
|
17074
|
+
const info = await socket.upgradeSecure(secure(supportOf(proc.net), req, servername));
|
|
17075
|
+
return sessionOf(info, servername);
|
|
17076
|
+
}
|
|
17077
|
+
|
|
16519
17078
|
// src/kernel/unix-dgram.ts
|
|
16520
17079
|
var SOL_SOCKET3 = 1;
|
|
16521
17080
|
var SO_TYPE3 = 3;
|
|
@@ -16677,7 +17236,8 @@ var SOCKET_OPS = [
|
|
|
16677
17236
|
"sock-resolve",
|
|
16678
17237
|
"sock-sendto",
|
|
16679
17238
|
"sock-recvfrom",
|
|
16680
|
-
"sock-tls"
|
|
17239
|
+
"sock-tls",
|
|
17240
|
+
"sock-tls-upgrade"
|
|
16681
17241
|
];
|
|
16682
17242
|
function socketAt(fds, fd) {
|
|
16683
17243
|
const file = anySocketAt(fds, fd);
|
|
@@ -16750,7 +17310,9 @@ async function socketSyscall(req, proc) {
|
|
|
16750
17310
|
return ok3(addresses);
|
|
16751
17311
|
}
|
|
16752
17312
|
case "sock-tls":
|
|
16753
|
-
return ok3(
|
|
17313
|
+
return ok3(await secureConnect(req, proc));
|
|
17314
|
+
case "sock-tls-upgrade":
|
|
17315
|
+
return ok3(await upgradeSecure(proc, socketAt(fds, req.fd), req));
|
|
16754
17316
|
default:
|
|
16755
17317
|
return datagram(req, proc);
|
|
16756
17318
|
}
|
|
@@ -16872,6 +17434,36 @@ var NOT_HTTP_PORTS = /* @__PURE__ */ new Set([
|
|
|
16872
17434
|
8883
|
|
16873
17435
|
]);
|
|
16874
17436
|
var HOST_NAME = /^[A-Za-z0-9.-]+$|^\[?[0-9A-Fa-f:.]+\]?$/;
|
|
17437
|
+
function wantsKernel(req) {
|
|
17438
|
+
if (req.path === "kernel") return true;
|
|
17439
|
+
if (req.path === "transport") return false;
|
|
17440
|
+
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);
|
|
17441
|
+
}
|
|
17442
|
+
async function secureConnect(req, proc) {
|
|
17443
|
+
if (!Number.isInteger(req.port) || req.port < 1 || req.port > 65535)
|
|
17444
|
+
throw new KernelError("EINVAL");
|
|
17445
|
+
const kernelPath = wantsKernel(req) && await uplinked(proc, req.host);
|
|
17446
|
+
if (!kernelPath) {
|
|
17447
|
+
if (req.path === "kernel" || Array.isArray(req.ca)) throw new KernelError("ENOTSUP");
|
|
17448
|
+
return { ...tlsOverTransport(req, proc), path: "transport", substitutes: true };
|
|
17449
|
+
}
|
|
17450
|
+
const socket = proc.net.socket("inet");
|
|
17451
|
+
const fd = proc.fds.install(new OpenFile(socket), 3);
|
|
17452
|
+
try {
|
|
17453
|
+
return { fd, ...await connectSecure(proc, socket, req.host, req.port, req) };
|
|
17454
|
+
} catch (e) {
|
|
17455
|
+
await Promise.resolve(proc.fds.close(fd));
|
|
17456
|
+
throw e;
|
|
17457
|
+
}
|
|
17458
|
+
}
|
|
17459
|
+
async function uplinked(proc, host) {
|
|
17460
|
+
if (!proc.net.tlsClient || isLoopbackHost(host)) return false;
|
|
17461
|
+
try {
|
|
17462
|
+
return proc.net.uplinkFor(await uplinkAddress(proc, host)) !== void 0;
|
|
17463
|
+
} catch {
|
|
17464
|
+
return false;
|
|
17465
|
+
}
|
|
17466
|
+
}
|
|
16875
17467
|
function tlsOverTransport(req, proc) {
|
|
16876
17468
|
if (req.ca) throw new KernelError("ENOTSUP");
|
|
16877
17469
|
if (req.alpn && req.alpn.length > 0 && !req.alpn.includes("http/1.1")) {
|
|
@@ -19872,10 +20464,10 @@ var JobTable = class {
|
|
|
19872
20464
|
signalForeground(tty, fallback, sig) {
|
|
19873
20465
|
this.killGroup(this.tcgetpgrp(tty, fallback), sig);
|
|
19874
20466
|
}
|
|
19875
|
-
fromKeyboard(
|
|
20467
|
+
fromKeyboard(send2) {
|
|
19876
20468
|
this.keyboard = true;
|
|
19877
20469
|
try {
|
|
19878
|
-
|
|
20470
|
+
send2();
|
|
19879
20471
|
} finally {
|
|
19880
20472
|
this.keyboard = false;
|
|
19881
20473
|
}
|
|
@@ -20186,6 +20778,12 @@ var LockService = class {
|
|
|
20186
20778
|
lock(pid, path, exclusive, fd) {
|
|
20187
20779
|
return this.table.lock(pid, path, exclusive, fd);
|
|
20188
20780
|
}
|
|
20781
|
+
wholeFree(pid, path, exclusive) {
|
|
20782
|
+
return this.table.wholeFree(pid, path, exclusive);
|
|
20783
|
+
}
|
|
20784
|
+
flockFree(key, owner, kind) {
|
|
20785
|
+
return this.table.flockFree(key, owner, kind);
|
|
20786
|
+
}
|
|
20189
20787
|
unlock(pid, path) {
|
|
20190
20788
|
this.table.unlock(pid, path);
|
|
20191
20789
|
}
|
|
@@ -20861,7 +21459,7 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
|
|
|
20861
21459
|
await changed(signal);
|
|
20862
21460
|
}
|
|
20863
21461
|
};
|
|
20864
|
-
const
|
|
21462
|
+
const send2 = async (out, signal) => {
|
|
20865
21463
|
const write = file.write;
|
|
20866
21464
|
for (let at = 0; at < out.length; ) {
|
|
20867
21465
|
try {
|
|
@@ -20896,7 +21494,7 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
|
|
|
20896
21494
|
raise();
|
|
20897
21495
|
if (timer !== void 0) clearTimeout(timer);
|
|
20898
21496
|
timer = void 0;
|
|
20899
|
-
await
|
|
21497
|
+
await send2(stream2.push(taken), signal);
|
|
20900
21498
|
} finally {
|
|
20901
21499
|
busy = false;
|
|
20902
21500
|
if (quiet3()) wake();
|
|
@@ -21242,19 +21840,19 @@ var SettlingChildren = class {
|
|
|
21242
21840
|
this.held = this.held.filter((h) => this.blocking(h.pgid));
|
|
21243
21841
|
for (const h of ready2) h.send();
|
|
21244
21842
|
}
|
|
21245
|
-
deliver(sig, pgid,
|
|
21843
|
+
deliver(sig, pgid, send2, foreground) {
|
|
21246
21844
|
if (!KEY_SIGNALS.has(sig)) {
|
|
21247
|
-
|
|
21845
|
+
send2();
|
|
21248
21846
|
} else if (this.blocking(pgid)) {
|
|
21249
|
-
this.held.push({ pgid, send });
|
|
21847
|
+
this.held.push({ pgid, send: send2 });
|
|
21250
21848
|
} else if (foreground) {
|
|
21251
|
-
|
|
21849
|
+
send2();
|
|
21252
21850
|
const moved2 = () => {
|
|
21253
|
-
if (foreground() !== pgid)
|
|
21851
|
+
if (foreground() !== pgid) send2();
|
|
21254
21852
|
};
|
|
21255
21853
|
this.parked.push({ pgid, send: moved2 });
|
|
21256
21854
|
} else {
|
|
21257
|
-
|
|
21855
|
+
send2();
|
|
21258
21856
|
}
|
|
21259
21857
|
}
|
|
21260
21858
|
blocking(pgid) {
|
|
@@ -21399,9 +21997,9 @@ function serveFilesystem(port, handlers, capabilities = {}, options = {}) {
|
|
|
21399
21997
|
let open = false;
|
|
21400
21998
|
const reply = (message3, transfer = []) => port.postMessage(message3, transfer);
|
|
21401
21999
|
async function hello(message3) {
|
|
21402
|
-
const
|
|
21403
|
-
if (
|
|
21404
|
-
reply({ hello: { protocol: DRIVER_PROTOCOL, error:
|
|
22000
|
+
const refused3 = driverVersionError(message3.protocol);
|
|
22001
|
+
if (refused3) {
|
|
22002
|
+
reply({ hello: { protocol: DRIVER_PROTOCOL, error: refused3, errno: "EPROTO" } });
|
|
21405
22003
|
return;
|
|
21406
22004
|
}
|
|
21407
22005
|
try {
|
|
@@ -22386,7 +22984,7 @@ function serveHostfsPort(port, transport) {
|
|
|
22386
22984
|
});
|
|
22387
22985
|
handles.clear();
|
|
22388
22986
|
};
|
|
22389
|
-
const
|
|
22987
|
+
const send2 = (reply, transfer = []) => port.postMessage(reply, transfer);
|
|
22390
22988
|
const pending = /* @__PURE__ */ new Set();
|
|
22391
22989
|
const track = (work) => {
|
|
22392
22990
|
pending.add(work);
|
|
@@ -22406,7 +23004,7 @@ function serveHostfsPort(port, transport) {
|
|
|
22406
23004
|
data
|
|
22407
23005
|
}) => {
|
|
22408
23006
|
const { id: id2, op } = data;
|
|
22409
|
-
if (op === "ping") return
|
|
23007
|
+
if (op === "ping") return send2({ id: id2, pong: true });
|
|
22410
23008
|
if (op === "bye") return stop();
|
|
22411
23009
|
if (op === "cleanup")
|
|
22412
23010
|
return void Promise.allSettled([...pending]).then(() => answer(data.name, data.body)).catch(() => {
|
|
@@ -22418,12 +23016,12 @@ function serveHostfsPort(port, transport) {
|
|
|
22418
23016
|
try {
|
|
22419
23017
|
await transport.watch(
|
|
22420
23018
|
stop2.signal,
|
|
22421
|
-
(event) =>
|
|
22422
|
-
() =>
|
|
23019
|
+
(event) => send2({ id: id2, event }),
|
|
23020
|
+
() => send2({ id: id2, open: true })
|
|
22423
23021
|
);
|
|
22424
|
-
|
|
23022
|
+
send2({ id: id2, end: true });
|
|
22425
23023
|
} catch (err) {
|
|
22426
|
-
|
|
23024
|
+
send2({ id: id2, error: errorOf(err) });
|
|
22427
23025
|
} finally {
|
|
22428
23026
|
watches.delete(id2);
|
|
22429
23027
|
}
|
|
@@ -22440,18 +23038,18 @@ function serveHostfsPort(port, transport) {
|
|
|
22440
23038
|
)
|
|
22441
23039
|
);
|
|
22442
23040
|
const bytes = read.slice();
|
|
22443
|
-
return
|
|
23041
|
+
return send2({ id: id2, bytes }, [bytes.buffer]);
|
|
22444
23042
|
}
|
|
22445
23043
|
if (op === "write") {
|
|
22446
23044
|
await track(
|
|
22447
23045
|
transport.write(data.fh, data.offset, data.bytes)
|
|
22448
23046
|
);
|
|
22449
|
-
return
|
|
23047
|
+
return send2({ id: id2 });
|
|
22450
23048
|
}
|
|
22451
23049
|
if (op !== "call") throw fsError2("EINVAL", `unknown hostfs port op ${op}`);
|
|
22452
|
-
|
|
23050
|
+
send2({ id: id2, result: await answer(data.name, data.body) });
|
|
22453
23051
|
} catch (err) {
|
|
22454
|
-
|
|
23052
|
+
send2({ id: id2, error: errorOf(err) });
|
|
22455
23053
|
}
|
|
22456
23054
|
};
|
|
22457
23055
|
const stop = () => {
|
|
@@ -23538,9 +24136,9 @@ function interpreter(head) {
|
|
|
23538
24136
|
if (words2[0] === "-S") words2.shift();
|
|
23539
24137
|
return baseName2(words2[0] ?? "");
|
|
23540
24138
|
}
|
|
23541
|
-
function expandDefaults(
|
|
24139
|
+
function expandDefaults(defaults2, env) {
|
|
23542
24140
|
const out = {};
|
|
23543
|
-
for (const [key, value2] of Object.entries(
|
|
24141
|
+
for (const [key, value2] of Object.entries(defaults2 ?? {})) {
|
|
23544
24142
|
let missing4 = false;
|
|
23545
24143
|
const expanded = value2.replace(ENV_REFERENCE, (_, name2) => {
|
|
23546
24144
|
const set3 = Object.hasOwn(env, name2) ? env[name2] : void 0;
|
|
@@ -23790,6 +24388,7 @@ var Launcher = class {
|
|
|
23790
24388
|
enableNetwork(this.net, {
|
|
23791
24389
|
transport: this.transport,
|
|
23792
24390
|
engine: kernelTlsEngine(packageTlsEngine(this.verifiedFs(options.fs), this.modulesDir)),
|
|
24391
|
+
roots: packageTlsRoots(this.verifiedFs(options.fs), this.modulesDir),
|
|
23793
24392
|
ca: this.ca
|
|
23794
24393
|
});
|
|
23795
24394
|
enableCdp(this.net, this.cdp);
|
|
@@ -24202,13 +24801,13 @@ var Launcher = class {
|
|
|
24202
24801
|
if (planned?.target.copy) await need(g, "exec", planned.target.copy, R_OK | X_OK);
|
|
24203
24802
|
}
|
|
24204
24803
|
async checkedPlan(req, { ppid, cred, scope }, fds) {
|
|
24205
|
-
const
|
|
24804
|
+
const refused3 = async (err) => {
|
|
24206
24805
|
await fds.closeAll();
|
|
24207
24806
|
throw err.code === "EACCES" ? new SpawnError("EACCES") : err;
|
|
24208
24807
|
};
|
|
24209
|
-
const file = await this.execFile(req.file, req.cwd, this.execGuard(cred, ppid)).catch(
|
|
24808
|
+
const file = await this.execFile(req.file, req.cwd, this.execGuard(cred, ppid)).catch(refused3);
|
|
24210
24809
|
const planned = await this.plan(file, req.argv, req.cwd, scope, req.argv0);
|
|
24211
|
-
await this.mayExec(cred, { ...req, file, pid: ppid }, planned).catch(
|
|
24810
|
+
await this.mayExec(cred, { ...req, file, pid: ppid }, planned).catch(refused3);
|
|
24212
24811
|
if (planned) return planned;
|
|
24213
24812
|
await fds.closeAll();
|
|
24214
24813
|
throw new SpawnError(await this.unrunnable(file, req.cwd, scope));
|
|
@@ -25043,10 +25642,10 @@ var Launcher = class {
|
|
|
25043
25642
|
return childHandle(await this.admitted(parent.program.abi !== "js", given, fresh2));
|
|
25044
25643
|
};
|
|
25045
25644
|
}
|
|
25046
|
-
keySignal(tty, fallback, sig,
|
|
25645
|
+
keySignal(tty, fallback, sig, send2) {
|
|
25047
25646
|
const pgid = this.jobs.tcgetpgrp(tty, fallback);
|
|
25048
25647
|
const foreground = () => this.jobs.tcgetpgrp(tty, fallback);
|
|
25049
|
-
const keyed = () => this.jobs.fromKeyboard(
|
|
25648
|
+
const keyed = () => this.jobs.fromKeyboard(send2);
|
|
25050
25649
|
this.settling.deliver(sig, pgid, keyed, tty.reading ? void 0 : foreground);
|
|
25051
25650
|
}
|
|
25052
25651
|
async resolvePrefixes() {
|
|
@@ -25691,7 +26290,7 @@ function cronLocks() {
|
|
|
25691
26290
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
25692
26291
|
import { subscribe } from "node:diagnostics_channel";
|
|
25693
26292
|
import { lookup as lookup2 } from "node:dns/promises";
|
|
25694
|
-
import { isIP } from "node:net";
|
|
26293
|
+
import { isIP as isIP2 } from "node:net";
|
|
25695
26294
|
var DEVTOOLS_PORTS = [9222, 9223, 9224, 9225, 9226, 9227, 9228, 9229];
|
|
25696
26295
|
var METADATA_V6 = [64768, 3778, 0, 0, 0, 0, 0, 596].join(":");
|
|
25697
26296
|
var resolveHost = async (host) => (await lookup2(host, { all: true, verbatim: true })).map((a) => a.address);
|
|
@@ -25703,7 +26302,7 @@ function ipv4Place(address) {
|
|
|
25703
26302
|
}
|
|
25704
26303
|
function placeOf(address) {
|
|
25705
26304
|
const plain2 = address.replace(/^\[(.*)\]$/, "$1").toLowerCase();
|
|
25706
|
-
const kind =
|
|
26305
|
+
const kind = isIP2(plain2);
|
|
25707
26306
|
if (kind === 4) return ipv4Place(plain2);
|
|
25708
26307
|
if (kind !== 6) return void 0;
|
|
25709
26308
|
const words2 = hextets2(plain2);
|
|
@@ -25756,7 +26355,7 @@ function connectRefusal(address, port, place) {
|
|
|
25756
26355
|
}
|
|
25757
26356
|
async function addressesOf(host, resolve2) {
|
|
25758
26357
|
const plain2 = host.replace(/^\[(.*)\]$/, "$1");
|
|
25759
|
-
if (
|
|
26358
|
+
if (isIP2(plain2)) return [plain2];
|
|
25760
26359
|
if (loopbackName2(plain2)) return ["127.0.0.1"];
|
|
25761
26360
|
return resolve2(plain2).catch(() => []);
|
|
25762
26361
|
}
|
|
@@ -26091,7 +26690,7 @@ function isMemoryRoot(handle) {
|
|
|
26091
26690
|
|
|
26092
26691
|
// src/node/ws-diagnose.ts
|
|
26093
26692
|
import { lookup as lookup3 } from "node:dns/promises";
|
|
26094
|
-
import { isIP as
|
|
26693
|
+
import { isIP as isIP3, connect as tcp } from "node:net";
|
|
26095
26694
|
import { connect as tls } from "node:tls";
|
|
26096
26695
|
var PROBE_MS = 3e3;
|
|
26097
26696
|
var PASSED = /* @__PURE__ */ new Set(["ECONNREFUSED", "EHOSTUNREACH", "ENETUNREACH", "ETIMEDOUT", "ECONNRESET"]);
|
|
@@ -26111,9 +26710,9 @@ function abortable(work, signal) {
|
|
|
26111
26710
|
});
|
|
26112
26711
|
return Promise.race([work, aborted2]).finally(() => signal.removeEventListener("abort", stop));
|
|
26113
26712
|
}
|
|
26114
|
-
function probe(
|
|
26713
|
+
function probe(secure2, host, port, ms, signal) {
|
|
26115
26714
|
return new Promise((resolve2) => {
|
|
26116
|
-
const socket =
|
|
26715
|
+
const socket = secure2 ? tls({ host, port, ...isIP3(host) ? {} : { servername: host } }) : tcp({ host, port });
|
|
26117
26716
|
const stop = () => done4("ABORTED");
|
|
26118
26717
|
const done4 = (code) => {
|
|
26119
26718
|
clearTimeout(timer);
|
|
@@ -26123,7 +26722,7 @@ function probe(secure, host, port, ms, signal) {
|
|
|
26123
26722
|
};
|
|
26124
26723
|
const timer = setTimeout(() => done4("ETIMEDOUT"), ms);
|
|
26125
26724
|
signal?.addEventListener("abort", stop, { once: true });
|
|
26126
|
-
socket.once(
|
|
26725
|
+
socket.once(secure2 ? "secureConnect" : "connect", () => done4("EPROTO"));
|
|
26127
26726
|
socket.once("error", (e) => {
|
|
26128
26727
|
const code = codeOf7(e) ?? "";
|
|
26129
26728
|
done4(PASSED.has(code) ? code : "EPROTO");
|
|
@@ -26133,8 +26732,8 @@ function probe(secure, host, port, ms, signal) {
|
|
|
26133
26732
|
async function diagnose(url, ms = PROBE_MS, signal) {
|
|
26134
26733
|
const at = new URL(url);
|
|
26135
26734
|
const host = at.hostname.replace(/^\[(.*)\]$/, "$1");
|
|
26136
|
-
const
|
|
26137
|
-
const port = Number(at.port) || (
|
|
26735
|
+
const secure2 = at.protocol === "wss:";
|
|
26736
|
+
const port = Number(at.port) || (secure2 ? 443 : 80);
|
|
26138
26737
|
signal?.throwIfAborted();
|
|
26139
26738
|
try {
|
|
26140
26739
|
await abortable(lookup3(host), signal);
|
|
@@ -26142,7 +26741,7 @@ async function diagnose(url, ms = PROBE_MS, signal) {
|
|
|
26142
26741
|
if (signal?.aborted) throw signal.reason;
|
|
26143
26742
|
return NO_NAME.has(codeOf7(e) ?? "") ? "EAI_NONAME" : void 0;
|
|
26144
26743
|
}
|
|
26145
|
-
const code = await probe(
|
|
26744
|
+
const code = await probe(secure2, host, port, ms, signal);
|
|
26146
26745
|
signal?.throwIfAborted();
|
|
26147
26746
|
return code;
|
|
26148
26747
|
}
|
|
@@ -26912,7 +27511,7 @@ async function terminalOn(channel, argv, opts) {
|
|
|
26912
27511
|
);
|
|
26913
27512
|
done4.catch(started.reject);
|
|
26914
27513
|
const pid = await started.promise;
|
|
26915
|
-
const
|
|
27514
|
+
const send2 = (action) => void channel.call({ op: "terminal", terminal: id2, ...action }).catch(() => void 0);
|
|
26916
27515
|
return {
|
|
26917
27516
|
pid,
|
|
26918
27517
|
exited: done4,
|
|
@@ -26924,10 +27523,10 @@ async function terminalOn(channel, argv, opts) {
|
|
|
26924
27523
|
listener = next3;
|
|
26925
27524
|
if (next3) for (const bytes of backlog.splice(0)) next3(bytes);
|
|
26926
27525
|
},
|
|
26927
|
-
write: (data) =>
|
|
26928
|
-
resize: (cols, rows) =>
|
|
26929
|
-
signal: (name2) =>
|
|
26930
|
-
close: () =>
|
|
27526
|
+
write: (data) => send2({ action: "write", bytes: bytesOf2(data) }),
|
|
27527
|
+
resize: (cols, rows) => send2({ action: "resize", cols, rows }),
|
|
27528
|
+
signal: (name2) => send2({ action: "signal", signal: name2 }),
|
|
27529
|
+
close: () => send2({ action: "close" })
|
|
26931
27530
|
};
|
|
26932
27531
|
}
|
|
26933
27532
|
function fsOn(channel) {
|
|
@@ -27000,9 +27599,9 @@ async function greet(channel, lock, timeoutMs) {
|
|
|
27000
27599
|
} finally {
|
|
27001
27600
|
clearTimeout(timer);
|
|
27002
27601
|
}
|
|
27003
|
-
const
|
|
27004
|
-
if (
|
|
27005
|
-
const error = new Error(
|
|
27602
|
+
const refused3 = hello.error ?? versionError(hello.protocol);
|
|
27603
|
+
if (refused3) {
|
|
27604
|
+
const error = new Error(refused3);
|
|
27006
27605
|
channel.end(error);
|
|
27007
27606
|
throw error;
|
|
27008
27607
|
}
|