@ai-ecoverse/slicc-kernel 1.95.2 → 1.96.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 +19 -2
- package/dist/index.js +71 -8
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +556 -178
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +710 -604
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +581 -218
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +783 -677
- package/dist/process-worker.js.map +4 -4
- package/dist/testing.js +45 -1
- package/dist/testing.js.map +2 -2
- package/package.json +1 -1
package/dist/node.js
CHANGED
|
@@ -1251,6 +1251,149 @@ function wasiErrno(code) {
|
|
|
1251
1251
|
return WASI_ERRNO[code] ?? E.IO;
|
|
1252
1252
|
}
|
|
1253
1253
|
|
|
1254
|
+
// src/kernel/net/loopback-names.ts
|
|
1255
|
+
var HOST_LOOPBACK = "host.slicc.internal";
|
|
1256
|
+
var HOST_LOOPBACK_ADDRESS = [10, 0, 2, 2];
|
|
1257
|
+
var PAGE_LOOPBACK = "kernel.localhost";
|
|
1258
|
+
var PAGE_LOOPBACK_URL = `http://{port}.${PAGE_LOOPBACK}`;
|
|
1259
|
+
function toHostLoopback(href) {
|
|
1260
|
+
const url = new URL(href);
|
|
1261
|
+
if (url.hostname.replace(/\.$/, "").toLowerCase() !== HOST_LOOPBACK) return href;
|
|
1262
|
+
url.hostname = "127.0.0.1";
|
|
1263
|
+
return url.href;
|
|
1264
|
+
}
|
|
1265
|
+
var LOOPBACK_V4 = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
|
|
1266
|
+
var LOOPBACK_V6 = /* @__PURE__ */ new Set(["::1", "::", "0:0:0:0:0:0:0:1"]);
|
|
1267
|
+
var MAPPED_V4 = /^::ffff:7f[0-9a-f]{2}:[0-9a-f]{1,4}$/;
|
|
1268
|
+
var KERNEL_PORT = /^(\d{1,5})\.kernel\.localhost$/;
|
|
1269
|
+
var SCHEMES = {
|
|
1270
|
+
"http:": 80,
|
|
1271
|
+
"ws:": 80,
|
|
1272
|
+
"https:": 443,
|
|
1273
|
+
"wss:": 443
|
|
1274
|
+
};
|
|
1275
|
+
function isKernelLoopbackHost(hostname) {
|
|
1276
|
+
const host = hostname.replace(/^\[(.*)\]$/, "$1").replace(/\.$/, "").toLowerCase();
|
|
1277
|
+
return host === "localhost" || host.endsWith(".localhost") || host === "0.0.0.0" || LOOPBACK_V4.test(host) || LOOPBACK_V6.has(host) || MAPPED_V4.test(host);
|
|
1278
|
+
}
|
|
1279
|
+
function kernelLoopbackPort(href) {
|
|
1280
|
+
let url;
|
|
1281
|
+
try {
|
|
1282
|
+
url = new URL(href);
|
|
1283
|
+
} catch {
|
|
1284
|
+
return void 0;
|
|
1285
|
+
}
|
|
1286
|
+
const fallback = SCHEMES[url.protocol];
|
|
1287
|
+
if (fallback === void 0 || !isKernelLoopbackHost(url.hostname)) return void 0;
|
|
1288
|
+
const named = KERNEL_PORT.exec(url.hostname.replace(/\.$/, "").toLowerCase())?.[1];
|
|
1289
|
+
const port = Number(named ?? (url.port || fallback));
|
|
1290
|
+
return port >= 1 && port <= 65535 ? port : void 0;
|
|
1291
|
+
}
|
|
1292
|
+
var DEFAULT_HOSTNAME = "slicc";
|
|
1293
|
+
var HOSTNAME_ADDRESS = "127.0.1.1";
|
|
1294
|
+
var LIBC_HOSTNAMES = ["emscripten", "wasmer.sh"];
|
|
1295
|
+
var LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i;
|
|
1296
|
+
function reserved(name2) {
|
|
1297
|
+
const lower = name2.toLowerCase();
|
|
1298
|
+
return lower === "localhost" || lower.endsWith(".localhost") || lower === HOST_LOOPBACK || lower === "wasmer.sh" || /^\d+(\.\d+){3}$/.test(lower);
|
|
1299
|
+
}
|
|
1300
|
+
function isHostname(name2) {
|
|
1301
|
+
if (typeof name2 !== "string" || name2.length > 253 || reserved(name2)) return false;
|
|
1302
|
+
return name2.split(".").every((l) => LABEL.test(l));
|
|
1303
|
+
}
|
|
1304
|
+
function ownNames(hostname) {
|
|
1305
|
+
return [.../* @__PURE__ */ new Set([hostname.toLowerCase(), ...LIBC_HOSTNAMES])];
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
// src/kernel/net/routes.ts
|
|
1309
|
+
var HOST_ADDRESS = HOST_LOOPBACK_ADDRESS.join(".");
|
|
1310
|
+
function ipv4Bytes(text) {
|
|
1311
|
+
const parts2 = text.split(".");
|
|
1312
|
+
if (parts2.length !== 4 || !parts2.every((p) => /^\d{1,3}$/.test(p))) return void 0;
|
|
1313
|
+
const bytes = parts2.map(Number);
|
|
1314
|
+
return bytes.every((b) => b <= 255) ? bytes : void 0;
|
|
1315
|
+
}
|
|
1316
|
+
function ipv6Groups(text) {
|
|
1317
|
+
if (!text.includes(":")) return void 0;
|
|
1318
|
+
let canonical;
|
|
1319
|
+
try {
|
|
1320
|
+
canonical = new URL(`http://[${text}]/`).hostname.slice(1, -1);
|
|
1321
|
+
} catch {
|
|
1322
|
+
return void 0;
|
|
1323
|
+
}
|
|
1324
|
+
const [head, tail] = canonical.split("::");
|
|
1325
|
+
const part = (s) => s ? s.split(":").map((h) => Number.parseInt(h, 16)) : [];
|
|
1326
|
+
const front = part(head);
|
|
1327
|
+
const back = part(tail);
|
|
1328
|
+
return tail === void 0 ? front : [...front, ...new Array(8 - front.length - back.length).fill(0), ...back];
|
|
1329
|
+
}
|
|
1330
|
+
function toBits(values, width) {
|
|
1331
|
+
return values.reduce((acc, v) => acc << BigInt(width) | BigInt(v), 0n);
|
|
1332
|
+
}
|
|
1333
|
+
function addressBits(host) {
|
|
1334
|
+
const v4 = ipv4Bytes(host);
|
|
1335
|
+
if (v4) return { v6: false, bits: toBits(v4, 8) };
|
|
1336
|
+
const v6 = ipv6Groups(host);
|
|
1337
|
+
return v6 ? { v6: true, bits: toBits(v6, 16) } : void 0;
|
|
1338
|
+
}
|
|
1339
|
+
function parsePrefix(text) {
|
|
1340
|
+
const parts2 = text.trim().split("/");
|
|
1341
|
+
if (parts2.length > 2) return void 0;
|
|
1342
|
+
const [address = "", size] = parts2;
|
|
1343
|
+
const parsed2 = addressBits(address);
|
|
1344
|
+
if (!parsed2) return void 0;
|
|
1345
|
+
const max = parsed2.v6 ? 128 : 32;
|
|
1346
|
+
const length2 = size === void 0 ? max : /^\d{1,3}$/.test(size) ? Number(size) : -1;
|
|
1347
|
+
if (length2 < 0 || length2 > max) return void 0;
|
|
1348
|
+
return { ...parsed2, length: length2 };
|
|
1349
|
+
}
|
|
1350
|
+
function within(prefix, addr) {
|
|
1351
|
+
if (prefix.v6 !== addr.v6) return false;
|
|
1352
|
+
const shift = BigInt((prefix.v6 ? 128 : 32) - prefix.length);
|
|
1353
|
+
return addr.bits >> shift === prefix.bits >> shift;
|
|
1354
|
+
}
|
|
1355
|
+
var RESERVED = [
|
|
1356
|
+
"0.0.0.0/8",
|
|
1357
|
+
"127.0.0.0/8",
|
|
1358
|
+
"169.254.0.0/16",
|
|
1359
|
+
"224.0.0.0/4",
|
|
1360
|
+
"240.0.0.0/4",
|
|
1361
|
+
"::/96",
|
|
1362
|
+
"::ffff:0:0/96",
|
|
1363
|
+
"fe80::/10",
|
|
1364
|
+
"ff00::/8"
|
|
1365
|
+
].map((p) => parsePrefix(p));
|
|
1366
|
+
var Routes = class {
|
|
1367
|
+
table = [];
|
|
1368
|
+
exit = false;
|
|
1369
|
+
ipv6;
|
|
1370
|
+
constructor(ipv62 = false) {
|
|
1371
|
+
this.ipv6 = ipv62;
|
|
1372
|
+
}
|
|
1373
|
+
set(table) {
|
|
1374
|
+
const parsed2 = (table.prefixes ?? []).map(parsePrefix);
|
|
1375
|
+
const bad = (table.prefixes ?? []).find((_, i) => !parsed2[i]);
|
|
1376
|
+
if (bad !== void 0) throw new Error(`not an address prefix: ${bad}`);
|
|
1377
|
+
this.table = parsed2;
|
|
1378
|
+
this.exit = table.exit === true;
|
|
1379
|
+
}
|
|
1380
|
+
classify(host) {
|
|
1381
|
+
const name2 = host.toLowerCase().replace(/\.$/, "");
|
|
1382
|
+
if (name2 === "localhost" || name2.endsWith(".localhost") || name2 === "0.0.0.0") {
|
|
1383
|
+
return "loopback";
|
|
1384
|
+
}
|
|
1385
|
+
if (name2 === HOST_LOOPBACK || name2 === HOST_ADDRESS) return "host";
|
|
1386
|
+
const addr = addressBits(name2);
|
|
1387
|
+
if (!addr) return "unreachable";
|
|
1388
|
+
if (addr.v6 && addr.bits === 1n) return "loopback";
|
|
1389
|
+
if (!addr.v6 && addr.bits >> 24n === 127n) return "loopback";
|
|
1390
|
+
if (RESERVED.some((p) => within(p, addr))) return "reserved";
|
|
1391
|
+
if (addr.v6 && !this.ipv6) return "unreachable";
|
|
1392
|
+
if (this.exit || this.table.some((p) => within(p, addr))) return "uplink";
|
|
1393
|
+
return "unreachable";
|
|
1394
|
+
}
|
|
1395
|
+
};
|
|
1396
|
+
|
|
1254
1397
|
// src/kernel/net/uplink-socket.ts
|
|
1255
1398
|
var CHUNK = 64 * 1024;
|
|
1256
1399
|
function hostPort(text) {
|
|
@@ -1655,8 +1798,10 @@ function canonicalHost(host) {
|
|
|
1655
1798
|
function keyOf(addr) {
|
|
1656
1799
|
return addr.family === "inet" ? `inet:${addr.port}` : `unix:${addr.path}`;
|
|
1657
1800
|
}
|
|
1801
|
+
var LOCAL_ONLY = new Routes();
|
|
1658
1802
|
var LoopbackNet = class {
|
|
1659
1803
|
bound = /* @__PURE__ */ new Map();
|
|
1804
|
+
dgrams = /* @__PURE__ */ new Map();
|
|
1660
1805
|
activators = /* @__PURE__ */ new Map();
|
|
1661
1806
|
internal = /* @__PURE__ */ new Set();
|
|
1662
1807
|
reserved = /* @__PURE__ */ new Set();
|
|
@@ -1669,7 +1814,31 @@ var LoopbackNet = class {
|
|
|
1669
1814
|
uplinkFor(host) {
|
|
1670
1815
|
const route = this.route;
|
|
1671
1816
|
if (!route) return void 0;
|
|
1672
|
-
return
|
|
1817
|
+
return this.destination(host) === "uplink" ? route : void 0;
|
|
1818
|
+
}
|
|
1819
|
+
destination(host) {
|
|
1820
|
+
return (this.route?.routes ?? LOCAL_ONLY).classify(host);
|
|
1821
|
+
}
|
|
1822
|
+
bindDgram(socket, addr, kernel = false) {
|
|
1823
|
+
if (addr.family !== "inet") throw new KernelError("EAFNOSUPPORT");
|
|
1824
|
+
this.bindable(addr, kernel);
|
|
1825
|
+
const port = addr.port === 0 ? this.ephemeral() : addr.port;
|
|
1826
|
+
if (this.dgrams.has(port)) throw new KernelError("EADDRINUSE");
|
|
1827
|
+
this.dgrams.set(port, socket);
|
|
1828
|
+
return { ...addr, port };
|
|
1829
|
+
}
|
|
1830
|
+
releaseDgram(addr, socket) {
|
|
1831
|
+
if (this.dgrams.get(addr.port) === socket) this.dgrams.delete(addr.port);
|
|
1832
|
+
}
|
|
1833
|
+
deliverDgram(port, datagram2) {
|
|
1834
|
+
const target = this.dgrams.get(port);
|
|
1835
|
+
return target ? target.deliver(datagram2) : false;
|
|
1836
|
+
}
|
|
1837
|
+
bindable(addr, kernel) {
|
|
1838
|
+
if (addr.host !== "0.0.0.0" && !isLoopback(addr.host)) {
|
|
1839
|
+
throw new KernelError("EADDRNOTAVAIL");
|
|
1840
|
+
}
|
|
1841
|
+
if (!kernel && this.reserved.has(addr.port)) throw new KernelError("EADDRINUSE");
|
|
1673
1842
|
}
|
|
1674
1843
|
kernelOnly(port, reserve = false) {
|
|
1675
1844
|
if (reserve) this.internal.add(port);
|
|
@@ -1707,11 +1876,7 @@ var LoopbackNet = class {
|
|
|
1707
1876
|
bind(socket, addr, kernel = false) {
|
|
1708
1877
|
if (addr.family === "unix") {
|
|
1709
1878
|
if (addr.path === "") throw new KernelError("EINVAL");
|
|
1710
|
-
} else
|
|
1711
|
-
throw new KernelError("EADDRNOTAVAIL");
|
|
1712
|
-
} else if (!kernel && this.reserved.has(addr.port)) {
|
|
1713
|
-
throw new KernelError("EADDRINUSE");
|
|
1714
|
-
}
|
|
1879
|
+
} else this.bindable(addr, kernel);
|
|
1715
1880
|
const named = addr.family === "inet" && addr.port === 0 ? { ...addr, port: this.ephemeral() } : addr;
|
|
1716
1881
|
const key = keyOf(named);
|
|
1717
1882
|
if (this.bound.has(key)) throw new KernelError("EADDRINUSE");
|
|
@@ -1737,7 +1902,8 @@ var LoopbackNet = class {
|
|
|
1737
1902
|
for (let i = 0; i < span; i++) {
|
|
1738
1903
|
const port = this.nextEphemeral;
|
|
1739
1904
|
this.nextEphemeral = port === EPHEMERAL_LAST ? EPHEMERAL_FIRST : port + 1;
|
|
1740
|
-
|
|
1905
|
+
const taken = this.bound.has(`inet:${port}`) || this.dgrams.has(port);
|
|
1906
|
+
if (!taken && !this.reserved.has(port)) return port;
|
|
1741
1907
|
}
|
|
1742
1908
|
throw new KernelError("EADDRINUSE");
|
|
1743
1909
|
}
|
|
@@ -3485,14 +3651,14 @@ function protectedPrefixes(paths) {
|
|
|
3485
3651
|
}
|
|
3486
3652
|
return [...new Set(paths.map((p) => normalizePath(p)))];
|
|
3487
3653
|
}
|
|
3488
|
-
function
|
|
3654
|
+
function within2(path, prefix) {
|
|
3489
3655
|
return prefix === "/" || path === prefix || path.startsWith(`${prefix}/`);
|
|
3490
3656
|
}
|
|
3491
3657
|
function isProtected(prefixes2, path) {
|
|
3492
|
-
return prefixes2.some((prefix) =>
|
|
3658
|
+
return prefixes2.some((prefix) => within2(path, prefix));
|
|
3493
3659
|
}
|
|
3494
3660
|
function holdsProtected(prefixes2, path) {
|
|
3495
|
-
return prefixes2.some((prefix) =>
|
|
3661
|
+
return prefixes2.some((prefix) => within2(prefix, path));
|
|
3496
3662
|
}
|
|
3497
3663
|
var MAX_LINKS4 = 40;
|
|
3498
3664
|
function partsOf(path) {
|
|
@@ -3868,7 +4034,7 @@ function prefixes(path) {
|
|
|
3868
4034
|
const parts2 = split(path);
|
|
3869
4035
|
return parts2.map((_, i) => `/${parts2.slice(0, i + 1).join("/")}`);
|
|
3870
4036
|
}
|
|
3871
|
-
function
|
|
4037
|
+
function within3(path, root) {
|
|
3872
4038
|
return path === root || path.startsWith(`${root}/`);
|
|
3873
4039
|
}
|
|
3874
4040
|
var LOCKED = /* @__PURE__ */ new Set(["NotReadableError", "NoModificationAllowedError", "InvalidStateError"]);
|
|
@@ -4308,11 +4474,11 @@ var OpfsFs = class {
|
|
|
4308
4474
|
movePending(from, to) {
|
|
4309
4475
|
if (to !== void 0) {
|
|
4310
4476
|
for (const path of [...this.fileTimes.keys()]) {
|
|
4311
|
-
if (
|
|
4477
|
+
if (within3(path, to)) this.fileTimes.delete(path);
|
|
4312
4478
|
}
|
|
4313
4479
|
}
|
|
4314
4480
|
for (const [path, ms] of [...this.fileTimes]) {
|
|
4315
|
-
if (!
|
|
4481
|
+
if (!within3(path, from)) continue;
|
|
4316
4482
|
this.fileTimes.delete(path);
|
|
4317
4483
|
if (to !== void 0) this.fileTimes.set(to + path.slice(from.length), ms);
|
|
4318
4484
|
}
|
|
@@ -4736,7 +4902,7 @@ var OpfsFs = class {
|
|
|
4736
4902
|
}
|
|
4737
4903
|
async moveTo(source, parent, destination, to) {
|
|
4738
4904
|
const sourceStat = await this.describe(source);
|
|
4739
|
-
if (sourceStat.isDirectory &&
|
|
4905
|
+
if (sourceStat.isDirectory && within3(destination, source.path)) throw fsError("EINVAL", to);
|
|
4740
4906
|
const target = await this.locate(destination, false).catch((err) => {
|
|
4741
4907
|
if (missing2(err)) return null;
|
|
4742
4908
|
throw err;
|
|
@@ -4985,7 +5151,7 @@ function pidOwner(proc) {
|
|
|
4985
5151
|
function webLocks() {
|
|
4986
5152
|
return globalThis.navigator?.locks;
|
|
4987
5153
|
}
|
|
4988
|
-
var
|
|
5154
|
+
var within4 = (path, target) => path === target || target === "/" || path.startsWith(`${target}/`);
|
|
4989
5155
|
var parentOf5 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
|
|
4990
5156
|
var lockName = (instance) => `slicc-unlinked:${instance}`;
|
|
4991
5157
|
var dirOf = (root) => root === "/" ? `/${UNLINKED_DIR}` : `${root}/${UNLINKED_DIR}`;
|
|
@@ -5085,7 +5251,7 @@ var UnlinkedKeeper = class {
|
|
|
5085
5251
|
for (const holder of this.holders) {
|
|
5086
5252
|
if (holder.owns(target)) continue;
|
|
5087
5253
|
for (const path of holder.held()) {
|
|
5088
|
-
if (!
|
|
5254
|
+
if (!within4(path, target) || holder.isKept(path)) continue;
|
|
5089
5255
|
held.set(path, [...held.get(path) ?? [], holder]);
|
|
5090
5256
|
}
|
|
5091
5257
|
}
|
|
@@ -6316,60 +6482,6 @@ function binfmtOf(binfmts, path) {
|
|
|
6316
6482
|
return best === void 0 ? void 0 : binfmts.get(best);
|
|
6317
6483
|
}
|
|
6318
6484
|
|
|
6319
|
-
// src/kernel/net/loopback-names.ts
|
|
6320
|
-
var HOST_LOOPBACK = "host.slicc.internal";
|
|
6321
|
-
var HOST_LOOPBACK_ADDRESS = [10, 0, 2, 2];
|
|
6322
|
-
var PAGE_LOOPBACK = "kernel.localhost";
|
|
6323
|
-
var PAGE_LOOPBACK_URL = `http://{port}.${PAGE_LOOPBACK}`;
|
|
6324
|
-
function toHostLoopback(href) {
|
|
6325
|
-
const url = new URL(href);
|
|
6326
|
-
if (url.hostname.replace(/\.$/, "").toLowerCase() !== HOST_LOOPBACK) return href;
|
|
6327
|
-
url.hostname = "127.0.0.1";
|
|
6328
|
-
return url.href;
|
|
6329
|
-
}
|
|
6330
|
-
var LOOPBACK_V4 = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
|
|
6331
|
-
var LOOPBACK_V6 = /* @__PURE__ */ new Set(["::1", "::", "0:0:0:0:0:0:0:1"]);
|
|
6332
|
-
var MAPPED_V4 = /^::ffff:7f[0-9a-f]{2}:[0-9a-f]{1,4}$/;
|
|
6333
|
-
var KERNEL_PORT = /^(\d{1,5})\.kernel\.localhost$/;
|
|
6334
|
-
var SCHEMES = {
|
|
6335
|
-
"http:": 80,
|
|
6336
|
-
"ws:": 80,
|
|
6337
|
-
"https:": 443,
|
|
6338
|
-
"wss:": 443
|
|
6339
|
-
};
|
|
6340
|
-
function isKernelLoopbackHost(hostname) {
|
|
6341
|
-
const host = hostname.replace(/^\[(.*)\]$/, "$1").replace(/\.$/, "").toLowerCase();
|
|
6342
|
-
return host === "localhost" || host.endsWith(".localhost") || host === "0.0.0.0" || LOOPBACK_V4.test(host) || LOOPBACK_V6.has(host) || MAPPED_V4.test(host);
|
|
6343
|
-
}
|
|
6344
|
-
function kernelLoopbackPort(href) {
|
|
6345
|
-
let url;
|
|
6346
|
-
try {
|
|
6347
|
-
url = new URL(href);
|
|
6348
|
-
} catch {
|
|
6349
|
-
return void 0;
|
|
6350
|
-
}
|
|
6351
|
-
const fallback = SCHEMES[url.protocol];
|
|
6352
|
-
if (fallback === void 0 || !isKernelLoopbackHost(url.hostname)) return void 0;
|
|
6353
|
-
const named = KERNEL_PORT.exec(url.hostname.replace(/\.$/, "").toLowerCase())?.[1];
|
|
6354
|
-
const port = Number(named ?? (url.port || fallback));
|
|
6355
|
-
return port >= 1 && port <= 65535 ? port : void 0;
|
|
6356
|
-
}
|
|
6357
|
-
var DEFAULT_HOSTNAME = "slicc";
|
|
6358
|
-
var HOSTNAME_ADDRESS = "127.0.1.1";
|
|
6359
|
-
var LIBC_HOSTNAMES = ["emscripten", "wasmer.sh"];
|
|
6360
|
-
var LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i;
|
|
6361
|
-
function reserved(name2) {
|
|
6362
|
-
const lower = name2.toLowerCase();
|
|
6363
|
-
return lower === "localhost" || lower.endsWith(".localhost") || lower === HOST_LOOPBACK || lower === "wasmer.sh" || /^\d+(\.\d+){3}$/.test(lower);
|
|
6364
|
-
}
|
|
6365
|
-
function isHostname(name2) {
|
|
6366
|
-
if (typeof name2 !== "string" || name2.length > 253 || reserved(name2)) return false;
|
|
6367
|
-
return name2.split(".").every((l) => LABEL.test(l));
|
|
6368
|
-
}
|
|
6369
|
-
function ownNames(hostname) {
|
|
6370
|
-
return [.../* @__PURE__ */ new Set([hostname.toLowerCase(), ...LIBC_HOSTNAMES])];
|
|
6371
|
-
}
|
|
6372
|
-
|
|
6373
6485
|
// src/kernel/net/proxy-service.ts
|
|
6374
6486
|
var SEND_BUFFER2 = 1024 * 1024;
|
|
6375
6487
|
var TLS_HANDSHAKE = 22;
|
|
@@ -7371,7 +7483,7 @@ var DEFAULT_UMASK = 18;
|
|
|
7371
7483
|
function isModule(bytes) {
|
|
7372
7484
|
return MAGIC.every((b, i) => bytes[i] === b);
|
|
7373
7485
|
}
|
|
7374
|
-
function
|
|
7486
|
+
function within5(path, dir) {
|
|
7375
7487
|
return path.startsWith(dir === "/" ? "/" : `${dir}/`);
|
|
7376
7488
|
}
|
|
7377
7489
|
var FreshModules = class {
|
|
@@ -7395,10 +7507,10 @@ var FreshModules = class {
|
|
|
7395
7507
|
const target = normalizePath(to);
|
|
7396
7508
|
if (source === target) return;
|
|
7397
7509
|
for (const key of [...this.fresh.keys()]) {
|
|
7398
|
-
if (key === target ||
|
|
7510
|
+
if (key === target || within5(key, target)) this.fresh.delete(key);
|
|
7399
7511
|
}
|
|
7400
7512
|
for (const [key, fresh2] of [...this.fresh]) {
|
|
7401
|
-
if (key !== source && !
|
|
7513
|
+
if (key !== source && !within5(key, source)) continue;
|
|
7402
7514
|
this.fresh.delete(key);
|
|
7403
7515
|
this.fresh.set(target + key.slice(source.length), fresh2);
|
|
7404
7516
|
}
|
|
@@ -7440,7 +7552,7 @@ var FreshModules = class {
|
|
|
7440
7552
|
await fs.rm(path, options);
|
|
7441
7553
|
const at = normalizePath(path);
|
|
7442
7554
|
for (const key of [...this.fresh.keys()]) {
|
|
7443
|
-
if (key === at ||
|
|
7555
|
+
if (key === at || within5(key, at)) this.fresh.delete(key);
|
|
7444
7556
|
}
|
|
7445
7557
|
},
|
|
7446
7558
|
rename: async (from, to) => {
|
|
@@ -8221,7 +8333,7 @@ function linkedTo(mount, path) {
|
|
|
8221
8333
|
return own?.kind !== "directory" && (attr2.nlink ?? 1) > 1;
|
|
8222
8334
|
};
|
|
8223
8335
|
}
|
|
8224
|
-
var
|
|
8336
|
+
var within6 = (path, target) => path === target || target === "/" || path.startsWith(`${target}/`);
|
|
8225
8337
|
var HeldSet = class extends Set {
|
|
8226
8338
|
idle;
|
|
8227
8339
|
constructor(idle) {
|
|
@@ -8240,7 +8352,7 @@ var HeldSet = class extends Set {
|
|
|
8240
8352
|
}
|
|
8241
8353
|
};
|
|
8242
8354
|
function heldUnder(held, target) {
|
|
8243
|
-
for (const paths of held) for (const path of paths.keys()) if (
|
|
8355
|
+
for (const paths of held) for (const path of paths.keys()) if (within6(path, target)) return true;
|
|
8244
8356
|
return false;
|
|
8245
8357
|
}
|
|
8246
8358
|
var HeldPaths = class extends Map {
|
|
@@ -8356,24 +8468,24 @@ var HeldPaths = class extends Map {
|
|
|
8356
8468
|
return this.owning === path;
|
|
8357
8469
|
}
|
|
8358
8470
|
revoke(prefix) {
|
|
8359
|
-
for (const path of this.keys()) if (
|
|
8471
|
+
for (const path of this.keys()) if (within6(path, prefix)) this.revoked.add(path);
|
|
8360
8472
|
}
|
|
8361
8473
|
renamed(from, to) {
|
|
8362
8474
|
for (const [path, count2] of [...this]) {
|
|
8363
|
-
if (!
|
|
8475
|
+
if (!within6(path, from)) continue;
|
|
8364
8476
|
const moved2 = to + path.slice(from.length);
|
|
8365
8477
|
this.delete(path);
|
|
8366
8478
|
this.set(moved2, (this.get(moved2) ?? 0) + count2);
|
|
8367
8479
|
if (this.revoked.delete(path)) this.revoked.add(moved2);
|
|
8368
8480
|
}
|
|
8369
8481
|
for (const [path, count2] of [...this.opens]) {
|
|
8370
|
-
if (!
|
|
8482
|
+
if (!within6(path, from)) continue;
|
|
8371
8483
|
const moved2 = to + path.slice(from.length);
|
|
8372
8484
|
this.opens.delete(path);
|
|
8373
8485
|
this.opens.set(moved2, (this.opens.get(moved2) ?? 0) + count2);
|
|
8374
8486
|
}
|
|
8375
8487
|
for (const [id2, key] of this.handles) {
|
|
8376
|
-
if (
|
|
8488
|
+
if (within6(key, from)) this.handles.set(id2, to + key.slice(from.length));
|
|
8377
8489
|
}
|
|
8378
8490
|
}
|
|
8379
8491
|
isRevoked(path) {
|
|
@@ -8478,13 +8590,13 @@ var MountTable = class {
|
|
|
8478
8590
|
});
|
|
8479
8591
|
}
|
|
8480
8592
|
under(path) {
|
|
8481
|
-
for (const mount of this.mounts.values()) if (
|
|
8593
|
+
for (const mount of this.mounts.values()) if (within6(mount.target, path)) return true;
|
|
8482
8594
|
return false;
|
|
8483
8595
|
}
|
|
8484
8596
|
locate(path) {
|
|
8485
8597
|
let best;
|
|
8486
8598
|
for (const mount of this.mounts.values()) {
|
|
8487
|
-
if (
|
|
8599
|
+
if (within6(path, mount.target) && (!best || mount.target.length > best.target.length))
|
|
8488
8600
|
best = mount;
|
|
8489
8601
|
}
|
|
8490
8602
|
if (!best) return void 0;
|
|
@@ -8627,7 +8739,7 @@ var MountTable = class {
|
|
|
8627
8739
|
async commitUnder(prefix) {
|
|
8628
8740
|
const at = normalizePath(prefix);
|
|
8629
8741
|
await Promise.all(
|
|
8630
|
-
[...this.sessions.keys()].filter((p) =>
|
|
8742
|
+
[...this.sessions.keys()].filter((p) => within6(p, at)).map((p) => this.commit(p))
|
|
8631
8743
|
);
|
|
8632
8744
|
}
|
|
8633
8745
|
async commitOverlapping(real, offset, length2) {
|
|
@@ -8664,11 +8776,11 @@ var MountTable = class {
|
|
|
8664
8776
|
mount.epoch++;
|
|
8665
8777
|
const linked2 = mount.caps.links ? linkedTo(mount, path) : () => false;
|
|
8666
8778
|
for (const [key, cached] of [...mount.attrs])
|
|
8667
|
-
if (
|
|
8779
|
+
if (within6(key, path) || linked2(cached.value)) mount.attrs.delete(key);
|
|
8668
8780
|
mount.lists.delete(path);
|
|
8669
8781
|
mount.lists.delete(parentOf7(path));
|
|
8670
8782
|
for (const [key, cached] of [...mount.lists])
|
|
8671
|
-
if (
|
|
8783
|
+
if (within6(key, path) || cached.value.some((e) => linked2(e.attr))) mount.lists.delete(key);
|
|
8672
8784
|
}
|
|
8673
8785
|
async getattr(mount, path, rel2, settled = false) {
|
|
8674
8786
|
for (let round = 1; ; round++) {
|
|
@@ -8808,7 +8920,7 @@ var MountFs = class _MountFs {
|
|
|
8808
8920
|
if (redirects >= MAX_LINKS7) throw errnoError("ELOOP", paths[0]);
|
|
8809
8921
|
const at = paths.map((path) => {
|
|
8810
8922
|
const real = normalizePath(path);
|
|
8811
|
-
return
|
|
8923
|
+
return within6(real, moved2.of) ? normalizePath(moved2.to + real.slice(moved2.of.length)) : real;
|
|
8812
8924
|
});
|
|
8813
8925
|
return again(at, redirects + 1);
|
|
8814
8926
|
}
|
|
@@ -10401,6 +10513,282 @@ var ProcessClocks = class {
|
|
|
10401
10513
|
}
|
|
10402
10514
|
};
|
|
10403
10515
|
|
|
10516
|
+
// src/kernel/net/uplink.ts
|
|
10517
|
+
function carriesUdp(uplink) {
|
|
10518
|
+
return uplink.traits.udp === true && typeof uplink.udp === "function";
|
|
10519
|
+
}
|
|
10520
|
+
function answerOf(result) {
|
|
10521
|
+
const answer = Array.isArray(result) ? { addresses: result } : result;
|
|
10522
|
+
const addresses = Array.isArray(answer?.addresses) ? answer.addresses.filter((a) => typeof a === "string") : [];
|
|
10523
|
+
return {
|
|
10524
|
+
addresses,
|
|
10525
|
+
...typeof answer?.ttl === "number" && answer.ttl >= 0 ? { ttl: answer.ttl } : {}
|
|
10526
|
+
};
|
|
10527
|
+
}
|
|
10528
|
+
var NEVER = new Routes(true);
|
|
10529
|
+
|
|
10530
|
+
// src/kernel/dgram.ts
|
|
10531
|
+
var DGRAM_QUEUE_BYTES = 256 * 1024;
|
|
10532
|
+
var DGRAM_QUEUE_COUNT = 512;
|
|
10533
|
+
var DGRAM_SEND_ROOM = 256 * 1024;
|
|
10534
|
+
var MAX_DATAGRAM_V4 = 65507;
|
|
10535
|
+
var MAX_DATAGRAM_V6 = 65527;
|
|
10536
|
+
var SOL_SOCKET2 = 1;
|
|
10537
|
+
var IPPROTO_IP = 0;
|
|
10538
|
+
var SO_TYPE2 = 3;
|
|
10539
|
+
var SO_ERROR2 = 4;
|
|
10540
|
+
var SO_BROADCAST = 6;
|
|
10541
|
+
var SO_SNDBUF2 = 7;
|
|
10542
|
+
var SO_RCVBUF2 = 8;
|
|
10543
|
+
var SO_DOMAIN2 = 39;
|
|
10544
|
+
var SOCK_DGRAM = 2;
|
|
10545
|
+
var AF_INET2 = 2;
|
|
10546
|
+
var IP_MULTICAST_FIRST = 32;
|
|
10547
|
+
var IP_MULTICAST_LAST = 36;
|
|
10548
|
+
var SEND_ERRORS = ["ENETUNREACH", "EHOSTUNREACH", "EACCES", "EMSGSIZE"];
|
|
10549
|
+
var UNREACHABLE = ["EACCES", "ENETUNREACH", "EHOSTUNREACH"];
|
|
10550
|
+
function sendError(e) {
|
|
10551
|
+
if (e instanceof KernelError) return e;
|
|
10552
|
+
const code = e?.code;
|
|
10553
|
+
return new KernelError(SEND_ERRORS.find((errno2) => errno2 === code) ?? "EHOSTUNREACH");
|
|
10554
|
+
}
|
|
10555
|
+
function sameAddr(a, b) {
|
|
10556
|
+
return a.port === b.port && canonicalHost(a.host) === canonicalHost(b.host);
|
|
10557
|
+
}
|
|
10558
|
+
function familyOf(host) {
|
|
10559
|
+
return host.includes(":") ? 6 : 4;
|
|
10560
|
+
}
|
|
10561
|
+
var KernelDgram = class {
|
|
10562
|
+
local;
|
|
10563
|
+
peer;
|
|
10564
|
+
net;
|
|
10565
|
+
queue = [];
|
|
10566
|
+
queued = 0;
|
|
10567
|
+
pending;
|
|
10568
|
+
closed = false;
|
|
10569
|
+
sending = 0;
|
|
10570
|
+
changes = new Changes();
|
|
10571
|
+
options = /* @__PURE__ */ new Map();
|
|
10572
|
+
uplinks = /* @__PURE__ */ new Map();
|
|
10573
|
+
stop = new AbortController();
|
|
10574
|
+
constructor(net) {
|
|
10575
|
+
this.net = net;
|
|
10576
|
+
}
|
|
10577
|
+
bind(addr) {
|
|
10578
|
+
if (this.local) throw new KernelError("EINVAL");
|
|
10579
|
+
this.local = this.net.bindDgram(this, addr);
|
|
10580
|
+
}
|
|
10581
|
+
bound() {
|
|
10582
|
+
this.local ??= this.net.bindDgram(this, { family: "inet", host: "0.0.0.0", port: 0 });
|
|
10583
|
+
return this.local;
|
|
10584
|
+
}
|
|
10585
|
+
connectTo(addr) {
|
|
10586
|
+
if (addr.family !== "inet") throw new KernelError("EAFNOSUPPORT");
|
|
10587
|
+
this.route(addr.host);
|
|
10588
|
+
this.bound();
|
|
10589
|
+
this.peer = { family: "inet", host: canonicalHost(addr.host), port: addr.port };
|
|
10590
|
+
this.pending = void 0;
|
|
10591
|
+
this.drain((d) => sameAddr(d.from, addr));
|
|
10592
|
+
}
|
|
10593
|
+
drain(keep2) {
|
|
10594
|
+
const kept = this.queue.filter(keep2);
|
|
10595
|
+
this.queue.splice(0, this.queue.length, ...kept);
|
|
10596
|
+
this.queued = kept.reduce((sum, d) => sum + d.bytes.length, 0);
|
|
10597
|
+
}
|
|
10598
|
+
route(host) {
|
|
10599
|
+
const where = this.net.destination(host);
|
|
10600
|
+
if (where === "loopback" || where === "uplink") return where;
|
|
10601
|
+
throw new KernelError("ENETUNREACH");
|
|
10602
|
+
}
|
|
10603
|
+
takeError() {
|
|
10604
|
+
const pending = this.pending;
|
|
10605
|
+
this.pending = void 0;
|
|
10606
|
+
return pending;
|
|
10607
|
+
}
|
|
10608
|
+
async send(bytes, to) {
|
|
10609
|
+
if (this.closed) throw new KernelError("EBADF");
|
|
10610
|
+
const pending = this.takeError();
|
|
10611
|
+
if (pending) throw new KernelError(pending);
|
|
10612
|
+
const target = to ?? this.peer;
|
|
10613
|
+
if (!target) throw new KernelError("EDESTADDRREQ");
|
|
10614
|
+
if (target.family !== "inet") throw new KernelError("EAFNOSUPPORT");
|
|
10615
|
+
const max = familyOf(target.host) === 6 ? MAX_DATAGRAM_V6 : MAX_DATAGRAM_V4;
|
|
10616
|
+
if (bytes.length > max) throw new KernelError("EMSGSIZE");
|
|
10617
|
+
const where = this.route(target.host);
|
|
10618
|
+
const local = this.bound();
|
|
10619
|
+
if (where === "uplink") return this.sendUp(bytes, target);
|
|
10620
|
+
const from = {
|
|
10621
|
+
family: "inet",
|
|
10622
|
+
host: local.host === "0.0.0.0" ? "127.0.0.1" : local.host,
|
|
10623
|
+
port: local.port
|
|
10624
|
+
};
|
|
10625
|
+
const delivered = this.net.deliverDgram(target.port, { bytes: bytes.slice(), from });
|
|
10626
|
+
if (!delivered && this.peer && sameAddr(this.peer, target)) {
|
|
10627
|
+
this.pending = "ECONNREFUSED";
|
|
10628
|
+
this.changes.wake();
|
|
10629
|
+
}
|
|
10630
|
+
return bytes.length;
|
|
10631
|
+
}
|
|
10632
|
+
async sendUp(bytes, to) {
|
|
10633
|
+
const uplink = this.net.uplinkFor(to.host)?.uplink;
|
|
10634
|
+
if (!uplink || !carriesUdp(uplink)) throw new KernelError("ENETUNREACH");
|
|
10635
|
+
this.sending += bytes.length;
|
|
10636
|
+
try {
|
|
10637
|
+
const socket = await this.uplinkSocket(uplink, familyOf(to.host));
|
|
10638
|
+
await socket.send(bytes.slice(), to.host, to.port);
|
|
10639
|
+
} catch (e) {
|
|
10640
|
+
throw sendError(e);
|
|
10641
|
+
} finally {
|
|
10642
|
+
this.sending -= bytes.length;
|
|
10643
|
+
this.changes.wake();
|
|
10644
|
+
}
|
|
10645
|
+
return bytes.length;
|
|
10646
|
+
}
|
|
10647
|
+
uplinkSocket(uplink, family) {
|
|
10648
|
+
const known = this.uplinks.get(family);
|
|
10649
|
+
if (known !== void 0) return known;
|
|
10650
|
+
const opening2 = Promise.resolve().then(() => {
|
|
10651
|
+
if (!uplink.udp) throw new KernelError("ENETUNREACH");
|
|
10652
|
+
return uplink.udp({ family, signal: this.stop.signal });
|
|
10653
|
+
});
|
|
10654
|
+
this.uplinks.set(family, opening2);
|
|
10655
|
+
opening2.then(
|
|
10656
|
+
(socket) => {
|
|
10657
|
+
if (this.closed) {
|
|
10658
|
+
socket.close();
|
|
10659
|
+
return;
|
|
10660
|
+
}
|
|
10661
|
+
void this.pump(socket, family);
|
|
10662
|
+
},
|
|
10663
|
+
() => this.uplinks.delete(family)
|
|
10664
|
+
);
|
|
10665
|
+
return opening2;
|
|
10666
|
+
}
|
|
10667
|
+
async pump(socket, family) {
|
|
10668
|
+
const iterate = async () => {
|
|
10669
|
+
for await (const message3 of socket.messages) {
|
|
10670
|
+
if (this.closed) return;
|
|
10671
|
+
const from = { family: "inet", host: message3.host, port: message3.port };
|
|
10672
|
+
if ("bytes" in message3) this.deliver({ bytes: message3.bytes, from });
|
|
10673
|
+
else this.unreachable(message3.error, from);
|
|
10674
|
+
}
|
|
10675
|
+
};
|
|
10676
|
+
await iterate().catch(() => void 0);
|
|
10677
|
+
if (!this.closed) this.uplinks.delete(family);
|
|
10678
|
+
socket.close();
|
|
10679
|
+
}
|
|
10680
|
+
unreachable(error, from) {
|
|
10681
|
+
if (!this.peer || !sameAddr(this.peer, from)) return;
|
|
10682
|
+
this.pending = UNREACHABLE.find((errno2) => errno2 === error) ?? "EHOSTUNREACH";
|
|
10683
|
+
this.changes.wake();
|
|
10684
|
+
}
|
|
10685
|
+
deliver(datagram2) {
|
|
10686
|
+
if (this.closed) return false;
|
|
10687
|
+
if (this.peer && !sameAddr(this.peer, datagram2.from)) return true;
|
|
10688
|
+
const full = this.queue.length >= DGRAM_QUEUE_COUNT || this.queued + datagram2.bytes.length > DGRAM_QUEUE_BYTES;
|
|
10689
|
+
if (full) return true;
|
|
10690
|
+
this.queue.push(datagram2);
|
|
10691
|
+
this.queued += datagram2.bytes.length;
|
|
10692
|
+
this.changes.wake();
|
|
10693
|
+
return true;
|
|
10694
|
+
}
|
|
10695
|
+
async receive(max, peek, signal) {
|
|
10696
|
+
for (; ; ) {
|
|
10697
|
+
const pending = this.takeError();
|
|
10698
|
+
if (pending) throw new KernelError(pending);
|
|
10699
|
+
if (this.closed) throw new KernelError("EBADF");
|
|
10700
|
+
const next2 = this.queue[0];
|
|
10701
|
+
if (next2) {
|
|
10702
|
+
if (!peek) {
|
|
10703
|
+
this.queue.shift();
|
|
10704
|
+
this.queued -= next2.bytes.length;
|
|
10705
|
+
this.changes.wake();
|
|
10706
|
+
}
|
|
10707
|
+
const size = Math.max(0, max);
|
|
10708
|
+
return {
|
|
10709
|
+
bytes: next2.bytes.slice(0, size),
|
|
10710
|
+
from: next2.from,
|
|
10711
|
+
truncated: next2.bytes.length > size
|
|
10712
|
+
};
|
|
10713
|
+
}
|
|
10714
|
+
await this.changes.wait(signal);
|
|
10715
|
+
}
|
|
10716
|
+
}
|
|
10717
|
+
async read(max, signal) {
|
|
10718
|
+
return (await this.receive(max, false, signal)).bytes;
|
|
10719
|
+
}
|
|
10720
|
+
async peek(max, signal) {
|
|
10721
|
+
return (await this.receive(max, true, signal)).bytes;
|
|
10722
|
+
}
|
|
10723
|
+
write(bytes) {
|
|
10724
|
+
return this.send(bytes);
|
|
10725
|
+
}
|
|
10726
|
+
poll() {
|
|
10727
|
+
return {
|
|
10728
|
+
readable: this.queue.length > 0 || this.pending !== void 0 || this.closed,
|
|
10729
|
+
writable: this.sending < DGRAM_SEND_ROOM,
|
|
10730
|
+
hangup: this.closed,
|
|
10731
|
+
...this.pending !== void 0 ? { error: true } : {}
|
|
10732
|
+
};
|
|
10733
|
+
}
|
|
10734
|
+
changed(signal) {
|
|
10735
|
+
return this.changes.wait(signal);
|
|
10736
|
+
}
|
|
10737
|
+
shutdown(how) {
|
|
10738
|
+
if (!this.peer) throw new KernelError("ENOTCONN");
|
|
10739
|
+
if (how < 0 || how > 2) throw new KernelError("EINVAL");
|
|
10740
|
+
}
|
|
10741
|
+
getOption(level, name2) {
|
|
10742
|
+
if (level === SOL_SOCKET2) {
|
|
10743
|
+
switch (name2) {
|
|
10744
|
+
case SO_TYPE2:
|
|
10745
|
+
return SOCK_DGRAM;
|
|
10746
|
+
case SO_ERROR2: {
|
|
10747
|
+
const pending = this.takeError();
|
|
10748
|
+
return pending ? wasiErrno(pending) : 0;
|
|
10749
|
+
}
|
|
10750
|
+
case SO_DOMAIN2:
|
|
10751
|
+
return AF_INET2;
|
|
10752
|
+
case SO_BROADCAST:
|
|
10753
|
+
return 0;
|
|
10754
|
+
case SO_SNDBUF2:
|
|
10755
|
+
return this.options.get(`${level}:${name2}`) ?? DGRAM_SEND_ROOM;
|
|
10756
|
+
case SO_RCVBUF2:
|
|
10757
|
+
return this.options.get(`${level}:${name2}`) ?? DGRAM_QUEUE_BYTES;
|
|
10758
|
+
}
|
|
10759
|
+
}
|
|
10760
|
+
if (level === IPPROTO_IP && name2 >= IP_MULTICAST_FIRST && name2 <= IP_MULTICAST_LAST) {
|
|
10761
|
+
throw new KernelError("ENOPROTOOPT");
|
|
10762
|
+
}
|
|
10763
|
+
return this.options.get(`${level}:${name2}`) ?? 0;
|
|
10764
|
+
}
|
|
10765
|
+
setOption(level, name2, value) {
|
|
10766
|
+
if (level === SOL_SOCKET2 && name2 === SO_BROADCAST && value !== 0) {
|
|
10767
|
+
throw new KernelError("EOPNOTSUPP");
|
|
10768
|
+
}
|
|
10769
|
+
if (level === IPPROTO_IP && name2 >= IP_MULTICAST_FIRST && name2 <= IP_MULTICAST_LAST) {
|
|
10770
|
+
throw new KernelError("ENOPROTOOPT");
|
|
10771
|
+
}
|
|
10772
|
+
this.options.set(`${level}:${name2}`, value);
|
|
10773
|
+
}
|
|
10774
|
+
close() {
|
|
10775
|
+
if (this.closed) return;
|
|
10776
|
+
this.closed = true;
|
|
10777
|
+
this.stop.abort();
|
|
10778
|
+
for (const opening2 of this.uplinks.values()) {
|
|
10779
|
+
opening2.then(
|
|
10780
|
+
(socket) => socket.close(),
|
|
10781
|
+
() => void 0
|
|
10782
|
+
);
|
|
10783
|
+
}
|
|
10784
|
+
this.uplinks.clear();
|
|
10785
|
+
if (this.local) this.net.releaseDgram(this.local, this);
|
|
10786
|
+
this.queue.length = 0;
|
|
10787
|
+
this.queued = 0;
|
|
10788
|
+
this.changes.wake();
|
|
10789
|
+
}
|
|
10790
|
+
};
|
|
10791
|
+
|
|
10404
10792
|
// src/fs/pages.ts
|
|
10405
10793
|
var PAGE = 64 * 1024;
|
|
10406
10794
|
var READAHEAD = 1024 * 1024;
|
|
@@ -10659,7 +11047,7 @@ function mountTable(mounts = []) {
|
|
|
10659
11047
|
}
|
|
10660
11048
|
|
|
10661
11049
|
// src/version.ts
|
|
10662
|
-
var KERNEL_VERSION = true ? "1.
|
|
11050
|
+
var KERNEL_VERSION = true ? "1.96.0" : "0.0.0-dev";
|
|
10663
11051
|
var OS_RELEASE = "6.0.0-slicc";
|
|
10664
11052
|
function procVersion() {
|
|
10665
11053
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -11146,6 +11534,7 @@ function levelOf(file) {
|
|
|
11146
11534
|
if (state.readable) bits2 |= EPOLL.IN;
|
|
11147
11535
|
if (state.writable) bits2 |= EPOLL.OUT;
|
|
11148
11536
|
if (state.rdhup) bits2 |= EPOLL.RDHUP;
|
|
11537
|
+
if (state.error) bits2 |= EPOLL.ERR;
|
|
11149
11538
|
if (state.hangup) bits2 |= file.read ? EPOLL.HUP : EPOLL.ERR;
|
|
11150
11539
|
return bits2;
|
|
11151
11540
|
}
|
|
@@ -12839,106 +13228,6 @@ var HttpHandles = class {
|
|
|
12839
13228
|
}
|
|
12840
13229
|
};
|
|
12841
13230
|
|
|
12842
|
-
// src/kernel/net/routes.ts
|
|
12843
|
-
var HOST_ADDRESS = HOST_LOOPBACK_ADDRESS.join(".");
|
|
12844
|
-
function ipv4Bytes(text) {
|
|
12845
|
-
const parts2 = text.split(".");
|
|
12846
|
-
if (parts2.length !== 4 || !parts2.every((p) => /^\d{1,3}$/.test(p))) return void 0;
|
|
12847
|
-
const bytes = parts2.map(Number);
|
|
12848
|
-
return bytes.every((b) => b <= 255) ? bytes : void 0;
|
|
12849
|
-
}
|
|
12850
|
-
function ipv6Groups(text) {
|
|
12851
|
-
if (!text.includes(":")) return void 0;
|
|
12852
|
-
let canonical;
|
|
12853
|
-
try {
|
|
12854
|
-
canonical = new URL(`http://[${text}]/`).hostname.slice(1, -1);
|
|
12855
|
-
} catch {
|
|
12856
|
-
return void 0;
|
|
12857
|
-
}
|
|
12858
|
-
const [head, tail] = canonical.split("::");
|
|
12859
|
-
const part = (s) => s ? s.split(":").map((h) => Number.parseInt(h, 16)) : [];
|
|
12860
|
-
const front = part(head);
|
|
12861
|
-
const back = part(tail);
|
|
12862
|
-
return tail === void 0 ? front : [...front, ...new Array(8 - front.length - back.length).fill(0), ...back];
|
|
12863
|
-
}
|
|
12864
|
-
function toBits(values, width) {
|
|
12865
|
-
return values.reduce((acc, v) => acc << BigInt(width) | BigInt(v), 0n);
|
|
12866
|
-
}
|
|
12867
|
-
function addressBits(host) {
|
|
12868
|
-
const v4 = ipv4Bytes(host);
|
|
12869
|
-
if (v4) return { v6: false, bits: toBits(v4, 8) };
|
|
12870
|
-
const v6 = ipv6Groups(host);
|
|
12871
|
-
return v6 ? { v6: true, bits: toBits(v6, 16) } : void 0;
|
|
12872
|
-
}
|
|
12873
|
-
function parsePrefix(text) {
|
|
12874
|
-
const parts2 = text.trim().split("/");
|
|
12875
|
-
if (parts2.length > 2) return void 0;
|
|
12876
|
-
const [address = "", size] = parts2;
|
|
12877
|
-
const parsed2 = addressBits(address);
|
|
12878
|
-
if (!parsed2) return void 0;
|
|
12879
|
-
const max = parsed2.v6 ? 128 : 32;
|
|
12880
|
-
const length2 = size === void 0 ? max : /^\d{1,3}$/.test(size) ? Number(size) : -1;
|
|
12881
|
-
if (length2 < 0 || length2 > max) return void 0;
|
|
12882
|
-
return { ...parsed2, length: length2 };
|
|
12883
|
-
}
|
|
12884
|
-
function within6(prefix, addr) {
|
|
12885
|
-
if (prefix.v6 !== addr.v6) return false;
|
|
12886
|
-
const shift = BigInt((prefix.v6 ? 128 : 32) - prefix.length);
|
|
12887
|
-
return addr.bits >> shift === prefix.bits >> shift;
|
|
12888
|
-
}
|
|
12889
|
-
var RESERVED = [
|
|
12890
|
-
"0.0.0.0/8",
|
|
12891
|
-
"127.0.0.0/8",
|
|
12892
|
-
"169.254.0.0/16",
|
|
12893
|
-
"224.0.0.0/4",
|
|
12894
|
-
"240.0.0.0/4",
|
|
12895
|
-
"::/96",
|
|
12896
|
-
"::ffff:0:0/96",
|
|
12897
|
-
"fe80::/10",
|
|
12898
|
-
"ff00::/8"
|
|
12899
|
-
].map((p) => parsePrefix(p));
|
|
12900
|
-
var Routes = class {
|
|
12901
|
-
table = [];
|
|
12902
|
-
exit = false;
|
|
12903
|
-
ipv6;
|
|
12904
|
-
constructor(ipv62 = false) {
|
|
12905
|
-
this.ipv6 = ipv62;
|
|
12906
|
-
}
|
|
12907
|
-
set(table) {
|
|
12908
|
-
const parsed2 = (table.prefixes ?? []).map(parsePrefix);
|
|
12909
|
-
const bad = (table.prefixes ?? []).find((_, i) => !parsed2[i]);
|
|
12910
|
-
if (bad !== void 0) throw new Error(`not an address prefix: ${bad}`);
|
|
12911
|
-
this.table = parsed2;
|
|
12912
|
-
this.exit = table.exit === true;
|
|
12913
|
-
}
|
|
12914
|
-
classify(host) {
|
|
12915
|
-
const name2 = host.toLowerCase().replace(/\.$/, "");
|
|
12916
|
-
if (name2 === "localhost" || name2.endsWith(".localhost") || name2 === "0.0.0.0") {
|
|
12917
|
-
return "loopback";
|
|
12918
|
-
}
|
|
12919
|
-
if (name2 === HOST_LOOPBACK || name2 === HOST_ADDRESS) return "host";
|
|
12920
|
-
const addr = addressBits(name2);
|
|
12921
|
-
if (!addr) return "unreachable";
|
|
12922
|
-
if (addr.v6 && addr.bits === 1n) return "loopback";
|
|
12923
|
-
if (!addr.v6 && addr.bits >> 24n === 127n) return "loopback";
|
|
12924
|
-
if (RESERVED.some((p) => within6(p, addr))) return "reserved";
|
|
12925
|
-
if (addr.v6 && !this.ipv6) return "unreachable";
|
|
12926
|
-
if (this.exit || this.table.some((p) => within6(p, addr))) return "uplink";
|
|
12927
|
-
return "unreachable";
|
|
12928
|
-
}
|
|
12929
|
-
};
|
|
12930
|
-
|
|
12931
|
-
// src/kernel/net/uplink.ts
|
|
12932
|
-
function answerOf(result) {
|
|
12933
|
-
const answer = Array.isArray(result) ? { addresses: result } : result;
|
|
12934
|
-
const addresses = Array.isArray(answer?.addresses) ? answer.addresses.filter((a) => typeof a === "string") : [];
|
|
12935
|
-
return {
|
|
12936
|
-
addresses,
|
|
12937
|
-
...typeof answer?.ttl === "number" && answer.ttl >= 0 ? { ttl: answer.ttl } : {}
|
|
12938
|
-
};
|
|
12939
|
-
}
|
|
12940
|
-
var NEVER = new Routes(true);
|
|
12941
|
-
|
|
12942
13231
|
// src/kernel/net/resolver.ts
|
|
12943
13232
|
var RESOLVE_TTL_MAX = 60;
|
|
12944
13233
|
var RESOLVE_TIMEOUT_MS = 1e4;
|
|
@@ -13675,6 +13964,19 @@ async function waitReady(fds, read, write, deadline, interrupted3) {
|
|
|
13675
13964
|
}
|
|
13676
13965
|
}
|
|
13677
13966
|
|
|
13967
|
+
// src/kernel/net/datagram-wire.ts
|
|
13968
|
+
function encodeReceived(got) {
|
|
13969
|
+
const host = new TextEncoder().encode(got.host);
|
|
13970
|
+
const out = new Uint8Array(4 + host.length + got.bytes.length);
|
|
13971
|
+
const view2 = new DataView(out.buffer);
|
|
13972
|
+
view2.setUint8(0, got.truncated ? 1 : 0);
|
|
13973
|
+
view2.setUint16(1, got.port);
|
|
13974
|
+
view2.setUint8(3, host.length);
|
|
13975
|
+
out.set(host, 4);
|
|
13976
|
+
out.set(got.bytes, 4 + host.length);
|
|
13977
|
+
return out;
|
|
13978
|
+
}
|
|
13979
|
+
|
|
13678
13980
|
// src/kernel/socket-syscalls.ts
|
|
13679
13981
|
var SOCKET_OPS = [
|
|
13680
13982
|
"sock-open",
|
|
@@ -13687,19 +13989,36 @@ var SOCKET_OPS = [
|
|
|
13687
13989
|
"sock-name",
|
|
13688
13990
|
"sock-getopt",
|
|
13689
13991
|
"sock-setopt",
|
|
13690
|
-
"sock-resolve"
|
|
13992
|
+
"sock-resolve",
|
|
13993
|
+
"sock-sendto",
|
|
13994
|
+
"sock-recvfrom"
|
|
13691
13995
|
];
|
|
13692
13996
|
function socketAt(fds, fd) {
|
|
13997
|
+
const file = anySocketAt(fds, fd);
|
|
13998
|
+
if (file instanceof KernelDgram) throw new KernelError("EOPNOTSUPP");
|
|
13999
|
+
return file;
|
|
14000
|
+
}
|
|
14001
|
+
function anySocketAt(fds, fd) {
|
|
13693
14002
|
const file = fds.get(fd).file;
|
|
13694
|
-
if (!(file instanceof KernelSocket)
|
|
14003
|
+
if (!(file instanceof KernelSocket) && !(file instanceof KernelDgram)) {
|
|
14004
|
+
throw new KernelError("ENOTSOCK");
|
|
14005
|
+
}
|
|
14006
|
+
return file;
|
|
14007
|
+
}
|
|
14008
|
+
function dgramAt(fds, fd) {
|
|
14009
|
+
const file = anySocketAt(fds, fd);
|
|
14010
|
+
if (!(file instanceof KernelDgram)) throw new KernelError("EOPNOTSUPP");
|
|
13695
14011
|
return file;
|
|
13696
14012
|
}
|
|
13697
14013
|
var ok2 = (json5) => json5 === void 0 ? { ok: true, kind: "void" } : { ok: true, kind: "json", json: json5 };
|
|
13698
14014
|
async function socketSyscall(req, proc) {
|
|
13699
14015
|
const { fds, net } = proc;
|
|
13700
14016
|
switch (req.op) {
|
|
13701
|
-
case "sock-open":
|
|
13702
|
-
|
|
14017
|
+
case "sock-open": {
|
|
14018
|
+
if (req.type === "dgram" && req.domain !== "inet") throw new KernelError("EPROTONOSUPPORT");
|
|
14019
|
+
const file = req.type === "dgram" ? new KernelDgram(net) : net.socket(req.domain);
|
|
14020
|
+
return ok2(fds.install(new OpenFile(file), 3));
|
|
14021
|
+
}
|
|
13703
14022
|
case "sock-pair": {
|
|
13704
14023
|
const [a, b] = KernelSocket.pair(net, req.domain, proc.cred?.());
|
|
13705
14024
|
const first = fds.install(new OpenFile(a), 3);
|
|
@@ -13711,44 +14030,64 @@ async function socketSyscall(req, proc) {
|
|
|
13711
14030
|
}
|
|
13712
14031
|
}
|
|
13713
14032
|
case "sock-bind":
|
|
13714
|
-
|
|
14033
|
+
anySocketAt(fds, req.fd).bind(req.addr);
|
|
13715
14034
|
return ok2();
|
|
13716
14035
|
case "sock-listen":
|
|
13717
14036
|
socketAt(fds, req.fd).listen(req.backlog, proc.cred?.());
|
|
13718
14037
|
return ok2();
|
|
13719
14038
|
case "sock-accept":
|
|
13720
14039
|
return ok2(await accept(proc, req.fd, req.nonblock));
|
|
13721
|
-
case "sock-connect":
|
|
13722
|
-
|
|
13723
|
-
const stamp = net.facadeAt(req.addr) && await proc.stamp?.();
|
|
13724
|
-
const dialing = socket.connect(req.addr, true, proc.cred?.(), stamp || void 0);
|
|
13725
|
-
if (req.nonblock) {
|
|
13726
|
-
dialing?.catch(() => void 0);
|
|
13727
|
-
throw new KernelError("EINPROGRESS");
|
|
13728
|
-
}
|
|
13729
|
-
if (dialing !== void 0) await interruptible2(dialing, proc.blocking());
|
|
13730
|
-
return ok2();
|
|
13731
|
-
}
|
|
14040
|
+
case "sock-connect":
|
|
14041
|
+
return connect(req, proc);
|
|
13732
14042
|
case "sock-shutdown":
|
|
13733
|
-
|
|
14043
|
+
anySocketAt(fds, req.fd).shutdown(req.how);
|
|
13734
14044
|
return ok2();
|
|
13735
14045
|
case "sock-name": {
|
|
13736
|
-
const socket =
|
|
14046
|
+
const socket = anySocketAt(fds, req.fd);
|
|
13737
14047
|
const addr = req.peer ? socket.peer : socket.local;
|
|
13738
14048
|
if (req.peer && !addr) throw new KernelError("ENOTCONN");
|
|
13739
|
-
return ok2(addr ?? unnamed(socket.domain));
|
|
14049
|
+
return ok2(addr ?? unnamed(socket instanceof KernelDgram ? "inet" : socket.domain));
|
|
13740
14050
|
}
|
|
13741
14051
|
case "sock-getopt":
|
|
13742
|
-
return ok2(
|
|
14052
|
+
return ok2(anySocketAt(fds, req.fd).getOption(req.level, req.name));
|
|
13743
14053
|
case "sock-setopt":
|
|
13744
|
-
|
|
14054
|
+
anySocketAt(fds, req.fd).setOption(req.level, req.name, req.value);
|
|
13745
14055
|
return ok2();
|
|
13746
14056
|
case "sock-resolve": {
|
|
13747
14057
|
const addresses = await proc.resolve(req.name, req.family, () => proc.blocking());
|
|
13748
14058
|
if (addresses.length === 0) throw new KernelError("ENOENT");
|
|
13749
14059
|
return ok2(addresses);
|
|
13750
14060
|
}
|
|
14061
|
+
default:
|
|
14062
|
+
return datagram(req, proc);
|
|
14063
|
+
}
|
|
14064
|
+
}
|
|
14065
|
+
async function connect(req, proc) {
|
|
14066
|
+
const target = anySocketAt(proc.fds, req.fd);
|
|
14067
|
+
if (target instanceof KernelDgram) {
|
|
14068
|
+
target.connectTo(req.addr);
|
|
14069
|
+
return ok2();
|
|
14070
|
+
}
|
|
14071
|
+
const stamp = proc.net.facadeAt(req.addr) && await proc.stamp?.();
|
|
14072
|
+
const dialing = target.connect(req.addr, true, proc.cred?.(), stamp || void 0);
|
|
14073
|
+
if (req.nonblock) {
|
|
14074
|
+
dialing?.catch(() => void 0);
|
|
14075
|
+
throw new KernelError("EINPROGRESS");
|
|
13751
14076
|
}
|
|
14077
|
+
if (dialing !== void 0) await interruptible2(dialing, proc.blocking());
|
|
14078
|
+
return ok2();
|
|
14079
|
+
}
|
|
14080
|
+
async function datagram(req, proc) {
|
|
14081
|
+
const dgram = dgramAt(proc.fds, req.fd);
|
|
14082
|
+
if (req.op === "sock-sendto") {
|
|
14083
|
+
if (req.nonblock && !pollFile(dgram).writable) throw new KernelError("EAGAIN");
|
|
14084
|
+
return ok2(await dgram.send(req.body, req.addr));
|
|
14085
|
+
}
|
|
14086
|
+
const ready2 = pollFile(dgram).readable;
|
|
14087
|
+
if (req.nonblock && !ready2) throw new KernelError("EAGAIN");
|
|
14088
|
+
const got = await dgram.receive(req.max, req.peek, ready2 ? void 0 : proc.blocking());
|
|
14089
|
+
const { bytes, from, truncated } = got;
|
|
14090
|
+
return { ok: true, kind: "bytes", bytes: encodeReceived({ bytes, truncated, ...from }) };
|
|
13752
14091
|
}
|
|
13753
14092
|
function interruptible2(dialing, signal) {
|
|
13754
14093
|
return new Promise((resolve2, reject) => {
|
|
@@ -15352,7 +15691,8 @@ var WasmProcess = class {
|
|
|
15352
15691
|
const terminal = (file.tty ?? file.pty?.slave)?.name;
|
|
15353
15692
|
return {
|
|
15354
15693
|
tty: file.tty !== void 0,
|
|
15355
|
-
kind: file instanceof KernelSocket ? "socket" : kernelFdKind(file),
|
|
15694
|
+
kind: file instanceof KernelSocket || file instanceof KernelDgram ? "socket" : kernelFdKind(file),
|
|
15695
|
+
...file instanceof KernelDgram ? { dgram: true } : {},
|
|
15356
15696
|
...file.heldMeta ? { meta: file.heldMeta } : {},
|
|
15357
15697
|
...flags2 !== void 0 ? { flags: flags2 } : {},
|
|
15358
15698
|
...this.fds.closesOnExec(fd) ? { cloexec: true } : {},
|
|
@@ -15741,7 +16081,7 @@ function inheritedFds(fds) {
|
|
|
15741
16081
|
return fds.numbers().filter((fd) => fd > 2 && !fds.get(fd).file.held).map((fd) => {
|
|
15742
16082
|
const open = fds.get(fd);
|
|
15743
16083
|
const flags2 = fds.statusFlags(fd);
|
|
15744
|
-
const kind = open.file instanceof KernelSocket ? "socket" : kernelFdKind(open.file);
|
|
16084
|
+
const kind = open.file instanceof KernelSocket || open.file instanceof KernelDgram ? "socket" : kernelFdKind(open.file);
|
|
15745
16085
|
const meta = open.file.heldMeta;
|
|
15746
16086
|
return {
|
|
15747
16087
|
fd,
|
|
@@ -18480,7 +18820,7 @@ function grantConnect(hook, fetch2, liveness = {}) {
|
|
|
18480
18820
|
return new HostfsClient(first, grant, fetch2);
|
|
18481
18821
|
};
|
|
18482
18822
|
}
|
|
18483
|
-
async function openHostfs(spec,
|
|
18823
|
+
async function openHostfs(spec, connect2, timing = {}) {
|
|
18484
18824
|
const readonly2 = spec.options?.ro !== void 0;
|
|
18485
18825
|
const { port1, port2 } = new MessageChannel();
|
|
18486
18826
|
const slot2 = mediumSlot(
|
|
@@ -18507,7 +18847,7 @@ async function openHostfs(spec, connect, timing = {}) {
|
|
|
18507
18847
|
);
|
|
18508
18848
|
const watching = keepWatching(
|
|
18509
18849
|
{
|
|
18510
|
-
connect: () =>
|
|
18850
|
+
connect: () => connect2(spec.source, { readonly: readonly2 }),
|
|
18511
18851
|
up(client) {
|
|
18512
18852
|
active = timed(client, timing.callMs ?? HOSTFS_CALL_MS);
|
|
18513
18853
|
slot2.insert(client, handlers);
|
|
@@ -21777,15 +22117,29 @@ function codeOf6(e) {
|
|
|
21777
22117
|
const code = e?.code;
|
|
21778
22118
|
return typeof code === "string" ? code : void 0;
|
|
21779
22119
|
}
|
|
21780
|
-
function
|
|
22120
|
+
function abortable(work, signal) {
|
|
22121
|
+
if (!signal) return work;
|
|
22122
|
+
if (signal.aborted) return Promise.reject(signal.reason);
|
|
22123
|
+
let stop = () => {
|
|
22124
|
+
};
|
|
22125
|
+
const aborted2 = new Promise((_, reject) => {
|
|
22126
|
+
stop = () => reject(signal.reason);
|
|
22127
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
22128
|
+
});
|
|
22129
|
+
return Promise.race([work, aborted2]).finally(() => signal.removeEventListener("abort", stop));
|
|
22130
|
+
}
|
|
22131
|
+
function probe(secure, host, port, ms, signal) {
|
|
21781
22132
|
return new Promise((resolve2) => {
|
|
21782
22133
|
const socket = secure ? tls({ host, port, ...isIP2(host) ? {} : { servername: host } }) : tcp({ host, port });
|
|
22134
|
+
const stop = () => done4("ABORTED");
|
|
21783
22135
|
const done4 = (code) => {
|
|
21784
22136
|
clearTimeout(timer);
|
|
22137
|
+
signal?.removeEventListener("abort", stop);
|
|
21785
22138
|
socket.destroy();
|
|
21786
22139
|
resolve2(code);
|
|
21787
22140
|
};
|
|
21788
22141
|
const timer = setTimeout(() => done4("ETIMEDOUT"), ms);
|
|
22142
|
+
signal?.addEventListener("abort", stop, { once: true });
|
|
21789
22143
|
socket.once(secure ? "secureConnect" : "connect", () => done4("EPROTO"));
|
|
21790
22144
|
socket.once("error", (e) => {
|
|
21791
22145
|
const code = codeOf6(e) ?? "";
|
|
@@ -21793,19 +22147,24 @@ function probe(secure, host, port, ms) {
|
|
|
21793
22147
|
});
|
|
21794
22148
|
});
|
|
21795
22149
|
}
|
|
21796
|
-
async function diagnose(url, ms = PROBE_MS) {
|
|
22150
|
+
async function diagnose(url, ms = PROBE_MS, signal) {
|
|
21797
22151
|
const at = new URL(url);
|
|
21798
22152
|
const host = at.hostname.replace(/^\[(.*)\]$/, "$1");
|
|
21799
22153
|
const secure = at.protocol === "wss:";
|
|
21800
22154
|
const port = Number(at.port) || (secure ? 443 : 80);
|
|
22155
|
+
signal?.throwIfAborted();
|
|
21801
22156
|
try {
|
|
21802
|
-
await lookup3(host);
|
|
22157
|
+
await abortable(lookup3(host), signal);
|
|
21803
22158
|
} catch (e) {
|
|
22159
|
+
if (signal?.aborted) throw signal.reason;
|
|
21804
22160
|
return NO_NAME.has(codeOf6(e) ?? "") ? "EAI_NONAME" : void 0;
|
|
21805
22161
|
}
|
|
21806
|
-
|
|
22162
|
+
const code = await probe(secure, host, port, ms, signal);
|
|
22163
|
+
signal?.throwIfAborted();
|
|
22164
|
+
return code;
|
|
21807
22165
|
}
|
|
21808
|
-
|
|
22166
|
+
var byDefault = (url, signal) => diagnose(url, PROBE_MS, signal);
|
|
22167
|
+
function diagnosing(transport, check = byDefault) {
|
|
21809
22168
|
const open = transport.websocket;
|
|
21810
22169
|
if (!open) return transport;
|
|
21811
22170
|
return {
|
|
@@ -21818,7 +22177,11 @@ function diagnosing(transport, check = diagnose) {
|
|
|
21818
22177
|
return await open(request);
|
|
21819
22178
|
} catch (e) {
|
|
21820
22179
|
if (request.signal.aborted || !(e instanceof Error) || codeOf6(e)) throw e;
|
|
21821
|
-
const code = await
|
|
22180
|
+
const code = await abortable(
|
|
22181
|
+
check(request.url, request.signal).catch(() => void 0),
|
|
22182
|
+
request.signal
|
|
22183
|
+
);
|
|
22184
|
+
request.signal.throwIfAborted();
|
|
21822
22185
|
throw code ? Object.assign(e, { code }) : e;
|
|
21823
22186
|
}
|
|
21824
22187
|
}
|