@ai-ecoverse/slicc-kernel 1.136.9 → 1.138.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 +21 -5
- package/dist/index.js +3 -1
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +675 -168
- package/dist/kernel-worker.js.map +4 -4
- package/dist/meta.js.map +1 -1
- package/dist/node-process-worker.js +58 -5
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +662 -164
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +58 -5
- package/dist/process-worker.js.map +4 -4
- package/dist/testing.js +1 -0
- package/dist/testing.js.map +2 -2
- package/dist/types/fs/notice.d.ts +1 -0
- package/dist/types/fs/opfs.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/kernel/net/dns-stub.d.ts +65 -0
- package/dist/types/kernel/net/resolver.d.ts +4 -1
- package/dist/types/kernel/net/uplink.d.ts +3 -1
- package/dist/types/kernel/proc-info.d.ts +2 -0
- package/dist/types/kernel/socket.d.ts +3 -1
- package/dist/types/launcher.d.ts +2 -0
- package/dist/types/node.d.ts +1 -0
- package/dist/types/process/procfs.d.ts +1 -1
- package/dist/types/process/wasi/wasi-procfs.d.ts +2 -1
- package/dist/types/serve.d.ts +2 -0
- package/dist/types/testing.d.ts +1 -0
- package/package.json +2 -2
package/dist/node.js
CHANGED
|
@@ -1319,6 +1319,15 @@ function isHostname(name2) {
|
|
|
1319
1319
|
function ownNames(hostname) {
|
|
1320
1320
|
return [.../* @__PURE__ */ new Set([hostname.toLowerCase(), ...LIBC_HOSTNAMES])];
|
|
1321
1321
|
}
|
|
1322
|
+
function hostsFile(hostname = DEFAULT_HOSTNAME) {
|
|
1323
|
+
return [
|
|
1324
|
+
"127.0.0.1 localhost localhost.localdomain",
|
|
1325
|
+
"::1 localhost ip6-localhost",
|
|
1326
|
+
`${HOSTNAME_ADDRESS} ${ownNames(hostname).join(" ")}`,
|
|
1327
|
+
`${HOST_LOOPBACK_ADDRESS.join(".")} ${HOST_LOOPBACK}`,
|
|
1328
|
+
""
|
|
1329
|
+
].join("\n");
|
|
1330
|
+
}
|
|
1322
1331
|
|
|
1323
1332
|
// src/kernel/net/routes.ts
|
|
1324
1333
|
var HOST_ADDRESS = HOST_LOOPBACK_ADDRESS.join(".");
|
|
@@ -2003,6 +2012,7 @@ var LOCAL_ONLY = new Routes();
|
|
|
2003
2012
|
var LoopbackNet = class {
|
|
2004
2013
|
bound = /* @__PURE__ */ new Map();
|
|
2005
2014
|
dgrams = /* @__PURE__ */ new Map();
|
|
2015
|
+
dgramServices = /* @__PURE__ */ new Map();
|
|
2006
2016
|
unixDgrams = /* @__PURE__ */ new Map();
|
|
2007
2017
|
activators = /* @__PURE__ */ new Map();
|
|
2008
2018
|
internal = /* @__PURE__ */ new Set();
|
|
@@ -2053,9 +2063,16 @@ var LoopbackNet = class {
|
|
|
2053
2063
|
releaseDgram(addr, socket) {
|
|
2054
2064
|
if (this.dgrams.get(addr.port) === socket) this.dgrams.delete(addr.port);
|
|
2055
2065
|
}
|
|
2056
|
-
|
|
2066
|
+
serveDgram(port, serve) {
|
|
2067
|
+
this.dgramServices.set(port, serve);
|
|
2068
|
+
}
|
|
2069
|
+
deliverDgram(port, datagram2, to) {
|
|
2057
2070
|
const target = this.dgrams.get(port);
|
|
2058
|
-
|
|
2071
|
+
if (target) return target.deliver(datagram2);
|
|
2072
|
+
const service = this.dgramServices.get(port);
|
|
2073
|
+
if (!service) return false;
|
|
2074
|
+
service(datagram2, to ?? { family: "inet", host: "127.0.0.1", port });
|
|
2075
|
+
return true;
|
|
2059
2076
|
}
|
|
2060
2077
|
bindable(addr, kernel) {
|
|
2061
2078
|
if (addr.host !== "0.0.0.0" && !isLoopback(addr.host)) {
|
|
@@ -3745,7 +3762,7 @@ function noticeOf(data) {
|
|
|
3745
3762
|
if (Array.isArray(data)) return { paths: data.filter((p) => typeof p === "string"), trees: [] };
|
|
3746
3763
|
const notice = data ?? {};
|
|
3747
3764
|
const strings = (list) => Array.isArray(list) ? list.filter((p) => typeof p === "string") : [];
|
|
3748
|
-
return { paths: strings(notice.paths), trees: strings(notice.trees) };
|
|
3765
|
+
return { paths: strings(notice.paths), trees: strings(notice.trees), outside: true };
|
|
3749
3766
|
}
|
|
3750
3767
|
|
|
3751
3768
|
// src/fs/integrity.ts
|
|
@@ -4564,9 +4581,11 @@ var OpfsFs = class {
|
|
|
4564
4581
|
for (const path of [...c.paths, ...c.trees]) this.forget(path);
|
|
4565
4582
|
});
|
|
4566
4583
|
this.channel.onmessage = ({ data }) => {
|
|
4567
|
-
const { paths, trees } = noticeOf(data);
|
|
4584
|
+
const { paths, trees, outside } = noticeOf(data);
|
|
4568
4585
|
for (const path of [...paths, ...trees]) this.forget(normalizePath(path));
|
|
4569
|
-
remote?.emit({ paths, trees });
|
|
4586
|
+
const tell = () => remote?.emit({ paths, trees });
|
|
4587
|
+
if (!outside) tell();
|
|
4588
|
+
else void this.noticed(paths.map(normalizePath), Date.now()).finally(tell);
|
|
4570
4589
|
};
|
|
4571
4590
|
this.channel.unref?.();
|
|
4572
4591
|
}
|
|
@@ -5025,6 +5044,14 @@ var OpfsFs = class {
|
|
|
5025
5044
|
this.fileTimes.set(target, Date.now());
|
|
5026
5045
|
this.scheduleFileTimes();
|
|
5027
5046
|
}
|
|
5047
|
+
async noticed(paths, at) {
|
|
5048
|
+
for (const path of new Set(paths)) {
|
|
5049
|
+
const st = await this.lstat(path).catch(() => void 0);
|
|
5050
|
+
if (!st?.isFile || st.mtime.getTime() >= at) continue;
|
|
5051
|
+
this.fileTimes.set(path, Math.max(at, this.fileTimes.get(path) ?? 0));
|
|
5052
|
+
}
|
|
5053
|
+
this.scheduleFileTimes();
|
|
5054
|
+
}
|
|
5028
5055
|
scheduleFileTimes() {
|
|
5029
5056
|
if (this.flushing.file || this.fileTimes.size === 0) return;
|
|
5030
5057
|
this.flushing.file = setTimeout(() => {
|
|
@@ -5684,8 +5711,8 @@ var OpfsFs = class {
|
|
|
5684
5711
|
renamingDirs = /* @__PURE__ */ new Set();
|
|
5685
5712
|
intents = 0;
|
|
5686
5713
|
async intend(rename, at = `${RENAMES}/${crypto.randomUUID()}`) {
|
|
5687
|
-
const
|
|
5688
|
-
await this.meta.update(at, () => ({ path: at, rename:
|
|
5714
|
+
const record2 = { ...rename, at: Date.now() * 1e3 + this.intents++ % 1e3 };
|
|
5715
|
+
await this.meta.update(at, () => ({ path: at, rename: record2 }));
|
|
5689
5716
|
return at;
|
|
5690
5717
|
}
|
|
5691
5718
|
async rollBack(from, to, intents) {
|
|
@@ -7486,7 +7513,7 @@ function satisfies(version, range2) {
|
|
|
7486
7513
|
}
|
|
7487
7514
|
|
|
7488
7515
|
// src/version.ts
|
|
7489
|
-
var KERNEL_VERSION = true ? "1.
|
|
7516
|
+
var KERNEL_VERSION = true ? "1.138.0" : "0.0.0-dev";
|
|
7490
7517
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7491
7518
|
function procVersion() {
|
|
7492
7519
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -8626,11 +8653,11 @@ var CronService = class {
|
|
|
8626
8653
|
}
|
|
8627
8654
|
if (this.stopping.signal.aborted) return;
|
|
8628
8655
|
const exit = ended.signal ? `signal=${ended.signal}` : `exit=${ended.status}`;
|
|
8629
|
-
const
|
|
8656
|
+
const header5 = encoder.encode(`--- ${iso} ${exit} missed=${missed} ---
|
|
8630
8657
|
`);
|
|
8631
8658
|
const body = output.bytes();
|
|
8632
8659
|
const newline = body.length > 0 && body[body.length - 1] !== 10 ? encoder.encode("\n") : new Uint8Array();
|
|
8633
|
-
await this.append(log, concat2([
|
|
8660
|
+
await this.append(log, concat2([header5, body, newline]), account.uid, account.gid).catch(
|
|
8634
8661
|
(err) => this.error(messageOf(err))
|
|
8635
8662
|
);
|
|
8636
8663
|
}
|
|
@@ -9438,8 +9465,8 @@ var FileWatches = class {
|
|
|
9438
9465
|
live = /* @__PURE__ */ new Set();
|
|
9439
9466
|
local;
|
|
9440
9467
|
remote;
|
|
9441
|
-
constructor(
|
|
9442
|
-
this.local =
|
|
9468
|
+
constructor(local2, remote) {
|
|
9469
|
+
this.local = local2;
|
|
9443
9470
|
this.remote = remote;
|
|
9444
9471
|
}
|
|
9445
9472
|
announce() {
|
|
@@ -13159,18 +13186,18 @@ var SAB_I_ASYNC = 14;
|
|
|
13159
13186
|
var SAB_I_STOP = 15;
|
|
13160
13187
|
var SAB_I_BLOCKED = 16;
|
|
13161
13188
|
var SAB_I_BLOCKED_HI = 17;
|
|
13162
|
-
function loadBlocked(
|
|
13163
|
-
return [Atomics.load(
|
|
13189
|
+
function loadBlocked(header5) {
|
|
13190
|
+
return [Atomics.load(header5, SAB_I_BLOCKED), Atomics.load(header5, SAB_I_BLOCKED_HI)];
|
|
13164
13191
|
}
|
|
13165
|
-
function storeBlocked(
|
|
13166
|
-
Atomics.store(
|
|
13167
|
-
Atomics.store(
|
|
13192
|
+
function storeBlocked(header5, [low, high]) {
|
|
13193
|
+
Atomics.store(header5, SAB_I_BLOCKED_HI, high);
|
|
13194
|
+
Atomics.store(header5, SAB_I_BLOCKED, low);
|
|
13168
13195
|
}
|
|
13169
13196
|
var anyBlocked = (mask) => mask !== void 0 && (mask[0] !== 0 || mask[1] !== 0);
|
|
13170
13197
|
var U32 = 2 ** 32;
|
|
13171
|
-
function storeU53(
|
|
13172
|
-
Atomics.store(
|
|
13173
|
-
Atomics.store(
|
|
13198
|
+
function storeU53(header5, lo, hi, value2) {
|
|
13199
|
+
Atomics.store(header5, hi, Math.floor(value2 / U32));
|
|
13200
|
+
Atomics.store(header5, lo, value2 % U32 | 0);
|
|
13174
13201
|
}
|
|
13175
13202
|
var SAB_STATE_READY = 2;
|
|
13176
13203
|
var SAB_STATUS_BYTES = 1;
|
|
@@ -13219,7 +13246,7 @@ function sabViews(sab) {
|
|
|
13219
13246
|
var PENDING_TTL_MS = SYNC_FS_REQUEST_TIMEOUT_MS + 5e3;
|
|
13220
13247
|
function attachSyncSabResponder(port, sab, token, opts) {
|
|
13221
13248
|
const views = sabViews(sab);
|
|
13222
|
-
const { header:
|
|
13249
|
+
const { header: header5, window } = views;
|
|
13223
13250
|
const pending = /* @__PURE__ */ new Map();
|
|
13224
13251
|
let disposed = false;
|
|
13225
13252
|
const { dispatch: dispatch2 } = opts;
|
|
@@ -13230,20 +13257,20 @@ function attachSyncSabResponder(port, sab, token, opts) {
|
|
|
13230
13257
|
pending.delete(id2);
|
|
13231
13258
|
}
|
|
13232
13259
|
function publish(id2, entry, offset) {
|
|
13233
|
-
if (Atomics.load(
|
|
13260
|
+
if (Atomics.load(header5, SAB_I_REQ) !== id2) {
|
|
13234
13261
|
drop(id2);
|
|
13235
13262
|
return;
|
|
13236
13263
|
}
|
|
13237
13264
|
const chunk2 = Math.min(window.byteLength, entry.payload.byteLength - offset);
|
|
13238
13265
|
if (chunk2 > 0) window.set(entry.payload.subarray(offset, offset + chunk2));
|
|
13239
|
-
Atomics.store(
|
|
13240
|
-
storeU53(
|
|
13241
|
-
Atomics.store(
|
|
13242
|
-
storeU53(
|
|
13243
|
-
Atomics.store(
|
|
13244
|
-
Atomics.store(
|
|
13245
|
-
Atomics.add(
|
|
13246
|
-
Atomics.notify(
|
|
13266
|
+
Atomics.store(header5, SAB_I_STATUS, entry.status);
|
|
13267
|
+
storeU53(header5, SAB_I_TOTAL, SAB_I_TOTAL_HI, entry.payload.byteLength);
|
|
13268
|
+
Atomics.store(header5, SAB_I_CHUNK, chunk2);
|
|
13269
|
+
storeU53(header5, SAB_I_OFFSET, SAB_I_OFFSET_HI, offset);
|
|
13270
|
+
Atomics.store(header5, SAB_I_SEQ, id2);
|
|
13271
|
+
Atomics.store(header5, SAB_I_STATE, SAB_STATE_READY);
|
|
13272
|
+
Atomics.add(header5, SAB_I_PUB, 1);
|
|
13273
|
+
Atomics.notify(header5, SAB_I_PUB);
|
|
13247
13274
|
if (offset + chunk2 >= entry.payload.byteLength) drop(id2);
|
|
13248
13275
|
else if (entry.timer) {
|
|
13249
13276
|
clearTimeout(entry.timer);
|
|
@@ -13458,6 +13485,15 @@ var ProcessClocks = class {
|
|
|
13458
13485
|
}
|
|
13459
13486
|
};
|
|
13460
13487
|
|
|
13488
|
+
// src/kernel/proc-info.ts
|
|
13489
|
+
function mayTrace(viewer, target) {
|
|
13490
|
+
const by = viewer?.cred;
|
|
13491
|
+
const of = target.cred;
|
|
13492
|
+
if (!by || !of || by.euid === 0) return true;
|
|
13493
|
+
const uid = of.ruid === by.euid && of.euid === by.euid && of.suid === by.euid;
|
|
13494
|
+
return uid && of.rgid === by.egid && of.egid === by.egid && of.sgid === by.egid;
|
|
13495
|
+
}
|
|
13496
|
+
|
|
13461
13497
|
// src/fs/pages.ts
|
|
13462
13498
|
var PAGE = 64 * 1024;
|
|
13463
13499
|
var READAHEAD = 1024 * 1024;
|
|
@@ -14013,7 +14049,16 @@ var ProcTree = class {
|
|
|
14013
14049
|
if (!/^[1-9]\d*$/.test(top) || !this.alive(Number(top))) return void 0;
|
|
14014
14050
|
if (leaf === "task") return this.task(Number(top), rest2);
|
|
14015
14051
|
if (rest2.length > 0) return void 0;
|
|
14016
|
-
if (leaf === void 0)
|
|
14052
|
+
if (leaf === void 0) {
|
|
14053
|
+
const exe = () => this.info(Number(top))?.exe === void 0 ? [] : ["exe"];
|
|
14054
|
+
return { kind: "dir", names: () => [...PID_NAMES, ...exe(), "task"] };
|
|
14055
|
+
}
|
|
14056
|
+
if (leaf === "exe") {
|
|
14057
|
+
const info = this.info(Number(top));
|
|
14058
|
+
if (info?.exe === void 0) return void 0;
|
|
14059
|
+
const denied2 = !mayTrace(this.ownInfo(), info);
|
|
14060
|
+
return { kind: "link", target: info.exe, ...denied2 ? { denied: denied2 } : {} };
|
|
14061
|
+
}
|
|
14017
14062
|
if (!PID_NAMES.includes(leaf)) return void 0;
|
|
14018
14063
|
return {
|
|
14019
14064
|
kind: "file",
|
|
@@ -14025,6 +14070,10 @@ var ProcTree = class {
|
|
|
14025
14070
|
}
|
|
14026
14071
|
};
|
|
14027
14072
|
}
|
|
14073
|
+
ownInfo() {
|
|
14074
|
+
const processes2 = this.listing().processes;
|
|
14075
|
+
return processes2.find((p) => p.tid === this.pid) ?? processes2.find((p) => p.pid === this.pid);
|
|
14076
|
+
}
|
|
14028
14077
|
info(pid) {
|
|
14029
14078
|
return this.listing().processes.find((p) => p.pid === pid);
|
|
14030
14079
|
}
|
|
@@ -14088,6 +14137,7 @@ var ProcTree = class {
|
|
|
14088
14137
|
readlink(path) {
|
|
14089
14138
|
const node = this.find(path, false);
|
|
14090
14139
|
if (node.kind !== "link") throw syncError("EINVAL", path);
|
|
14140
|
+
if (node.denied) throw syncError("EACCES", path);
|
|
14091
14141
|
return node.target;
|
|
14092
14142
|
}
|
|
14093
14143
|
exists(path) {
|
|
@@ -15492,8 +15542,8 @@ function sameCert(a, b) {
|
|
|
15492
15542
|
if (!a || !b) return a === b;
|
|
15493
15543
|
return a.cert.length === b.cert.length && a.cert.every((byte, i) => byte === b.cert[i]);
|
|
15494
15544
|
}
|
|
15495
|
-
function winner(current, expected,
|
|
15496
|
-
return sameCert(current, expected) ?
|
|
15545
|
+
function winner(current, expected, record2) {
|
|
15546
|
+
return sameCert(current, expected) ? record2 : current;
|
|
15497
15547
|
}
|
|
15498
15548
|
var DAY = 24 * 60 * 60 * 1e3;
|
|
15499
15549
|
var CA_LIFETIME = 3650 * DAY;
|
|
@@ -15510,14 +15560,14 @@ function validLeafName(host) {
|
|
|
15510
15560
|
}
|
|
15511
15561
|
var RealmCa = class _RealmCa {
|
|
15512
15562
|
record;
|
|
15513
|
-
constructor(
|
|
15514
|
-
this.record =
|
|
15563
|
+
constructor(record2) {
|
|
15564
|
+
this.record = record2;
|
|
15515
15565
|
}
|
|
15516
15566
|
static async open(owner, store, now = Date.now()) {
|
|
15517
15567
|
const stored = await store.get(owner).catch(() => void 0);
|
|
15518
15568
|
if (stored && stored.notAfter - now > CA_RENEW_BEFORE) return new _RealmCa(stored);
|
|
15519
|
-
const
|
|
15520
|
-
return new _RealmCa(await store.swap(owner, stored,
|
|
15569
|
+
const record2 = await _RealmCa.create(owner, now);
|
|
15570
|
+
return new _RealmCa(await store.swap(owner, stored, record2));
|
|
15521
15571
|
}
|
|
15522
15572
|
static async create(owner, now) {
|
|
15523
15573
|
const pair = await crypto.subtle.generateKey(ECDSA, false, ["sign", "verify"]);
|
|
@@ -15676,10 +15726,15 @@ var TlsEngine = class {
|
|
|
15676
15726
|
const m = this.clientModule();
|
|
15677
15727
|
if (servername.includes("\0")) throw new TlsError(-3, "tls engine: a server name has no NUL");
|
|
15678
15728
|
const wire = alpnWire(alpn);
|
|
15679
|
-
const
|
|
15729
|
+
const bytes = new TextEncoder().encode(servername);
|
|
15730
|
+
const name2 = this.put(bytes);
|
|
15680
15731
|
try {
|
|
15681
15732
|
const at = store?.ptr ?? 0;
|
|
15682
|
-
const
|
|
15733
|
+
const named = m._tls_client_new_name;
|
|
15734
|
+
const ptr = this.withBytes(
|
|
15735
|
+
wire,
|
|
15736
|
+
(p) => named ? named(at, name2, bytes.length, p, wire.length, flags2) : m._tls_client_new(at, name2, p, wire.length, flags2)
|
|
15737
|
+
);
|
|
15683
15738
|
if (!ptr) throw this.error(m._tls_last_error(), "tls client");
|
|
15684
15739
|
return new TlsSession(this, m, ptr);
|
|
15685
15740
|
} finally {
|
|
@@ -16047,8 +16102,8 @@ function memoryCaStore() {
|
|
|
16047
16102
|
const records = /* @__PURE__ */ new Map();
|
|
16048
16103
|
return {
|
|
16049
16104
|
get: async (owner) => records.get(owner),
|
|
16050
|
-
swap: async (owner, expected,
|
|
16051
|
-
const kept = winner(records.get(owner), expected,
|
|
16105
|
+
swap: async (owner, expected, record2) => {
|
|
16106
|
+
const kept = winner(records.get(owner), expected, record2);
|
|
16052
16107
|
records.set(owner, kept);
|
|
16053
16108
|
return kept;
|
|
16054
16109
|
}
|
|
@@ -16175,10 +16230,10 @@ var WsHandles = class {
|
|
|
16175
16230
|
open = /* @__PURE__ */ new Map();
|
|
16176
16231
|
next;
|
|
16177
16232
|
local;
|
|
16178
|
-
constructor(transport, next3,
|
|
16233
|
+
constructor(transport, next3, local2) {
|
|
16179
16234
|
this.transport = transport;
|
|
16180
16235
|
this.next = next3;
|
|
16181
|
-
this.local =
|
|
16236
|
+
this.local = local2;
|
|
16182
16237
|
}
|
|
16183
16238
|
owns(handle) {
|
|
16184
16239
|
return this.open.has(handle);
|
|
@@ -16207,8 +16262,8 @@ var WsHandles = class {
|
|
|
16207
16262
|
return { ok: true, kind: "json", json: handle };
|
|
16208
16263
|
}
|
|
16209
16264
|
async connect(handle, req, entry) {
|
|
16210
|
-
const { transport, local } = this;
|
|
16211
|
-
const port =
|
|
16265
|
+
const { transport, local: local2 } = this;
|
|
16266
|
+
const port = local2?.port(req.url);
|
|
16212
16267
|
const open = { protocols: req.protocols, headers: req.headers, signal: entry.abort.signal };
|
|
16213
16268
|
if (port === void 0 && (!transport.traits.websocket || !transport.websocket)) {
|
|
16214
16269
|
return fail("ENOTSUP", NO_WEBSOCKET2);
|
|
@@ -16218,7 +16273,7 @@ var WsHandles = class {
|
|
|
16218
16273
|
socket = port === void 0 ? await transport.websocket({
|
|
16219
16274
|
url: toHostLoopback(req.url),
|
|
16220
16275
|
...open
|
|
16221
|
-
}) : await
|
|
16276
|
+
}) : await local2.websocket({ url: req.url, ...open }, port);
|
|
16222
16277
|
} catch (e) {
|
|
16223
16278
|
return fail(errnoOf(e), message(e));
|
|
16224
16279
|
}
|
|
@@ -16349,11 +16404,11 @@ var HttpHandles = class {
|
|
|
16349
16404
|
ws;
|
|
16350
16405
|
owner;
|
|
16351
16406
|
local;
|
|
16352
|
-
constructor(transport, owner,
|
|
16407
|
+
constructor(transport, owner, local2) {
|
|
16353
16408
|
this.transport = transport;
|
|
16354
16409
|
this.owner = owner;
|
|
16355
|
-
this.local =
|
|
16356
|
-
this.ws = new WsHandles(transport, () => ++this.nextHandle,
|
|
16410
|
+
this.local = local2;
|
|
16411
|
+
this.ws = new WsHandles(transport, () => ++this.nextHandle, local2);
|
|
16357
16412
|
}
|
|
16358
16413
|
syscall(req) {
|
|
16359
16414
|
if (req.op.startsWith("net-ws-")) return this.ws.syscall(req);
|
|
@@ -16505,6 +16560,43 @@ var HttpHandles = class {
|
|
|
16505
16560
|
}
|
|
16506
16561
|
};
|
|
16507
16562
|
|
|
16563
|
+
// src/kernel/net/hosts-file.ts
|
|
16564
|
+
var HOSTS_PATH = "/etc/hosts";
|
|
16565
|
+
function parseHosts(text) {
|
|
16566
|
+
const table = /* @__PURE__ */ new Map();
|
|
16567
|
+
for (const raw2 of text.split("\n")) {
|
|
16568
|
+
const [address, ...names2] = raw2.replace(/#.*/, "").trim().split(/\s+/);
|
|
16569
|
+
if (!address || names2.length === 0) continue;
|
|
16570
|
+
if (ipv4Bytes(address) === void 0 && ipv6Groups(address) === void 0) continue;
|
|
16571
|
+
for (const name2 of names2) {
|
|
16572
|
+
const key = name2.toLowerCase().replace(/\.$/, "");
|
|
16573
|
+
const known = table.get(key) ?? [];
|
|
16574
|
+
if (!known.includes(address)) known.push(address);
|
|
16575
|
+
table.set(key, known);
|
|
16576
|
+
}
|
|
16577
|
+
}
|
|
16578
|
+
return table;
|
|
16579
|
+
}
|
|
16580
|
+
function hostsReader(fs, path = HOSTS_PATH) {
|
|
16581
|
+
let stamp = "";
|
|
16582
|
+
let table;
|
|
16583
|
+
return async () => {
|
|
16584
|
+
const st = await fs.stat(path).catch(() => void 0);
|
|
16585
|
+
if (!st?.isFile) {
|
|
16586
|
+
stamp = "";
|
|
16587
|
+
table = void 0;
|
|
16588
|
+
return void 0;
|
|
16589
|
+
}
|
|
16590
|
+
const now = `${st.ino}:${st.size}:${st.mtime.getTime()}`;
|
|
16591
|
+
if (now === stamp && table) return table;
|
|
16592
|
+
const text = await fs.readFile(path).catch(() => void 0);
|
|
16593
|
+
if (text === void 0) return void 0;
|
|
16594
|
+
stamp = now;
|
|
16595
|
+
table = parseHosts(text);
|
|
16596
|
+
return table;
|
|
16597
|
+
};
|
|
16598
|
+
}
|
|
16599
|
+
|
|
16508
16600
|
// src/kernel/net/uplink.ts
|
|
16509
16601
|
function carriesUdp(uplink) {
|
|
16510
16602
|
return uplink.traits.udp === true && typeof uplink.udp === "function";
|
|
@@ -16540,6 +16632,7 @@ var Resolver = class {
|
|
|
16540
16632
|
timeoutMs;
|
|
16541
16633
|
log;
|
|
16542
16634
|
own;
|
|
16635
|
+
builtin;
|
|
16543
16636
|
cache = /* @__PURE__ */ new Map();
|
|
16544
16637
|
pending = /* @__PURE__ */ new Map();
|
|
16545
16638
|
hosts;
|
|
@@ -16550,6 +16643,7 @@ var Resolver = class {
|
|
|
16550
16643
|
this.timeoutMs = options.timeoutMs ?? RESOLVE_TIMEOUT_MS;
|
|
16551
16644
|
this.log = options.log ?? ((message3) => console.warn(message3));
|
|
16552
16645
|
this.own = ownNames(options.hostname ?? DEFAULT_HOSTNAME);
|
|
16646
|
+
this.builtin = parseHosts(hostsFile(options.hostname ?? DEFAULT_HOSTNAME));
|
|
16553
16647
|
this.hosts = options.hosts;
|
|
16554
16648
|
}
|
|
16555
16649
|
async fromFile(key, family) {
|
|
@@ -16559,18 +16653,34 @@ var Resolver = class {
|
|
|
16559
16653
|
const v6 = listed.filter((a) => ipv4Bytes(a) === void 0);
|
|
16560
16654
|
return family === 4 ? v4 : family === 6 ? v6 : [...v4, ...v6];
|
|
16561
16655
|
}
|
|
16656
|
+
async known(name2) {
|
|
16657
|
+
const key = name2.toLowerCase().replace(/\.$/, "");
|
|
16658
|
+
if (ipv4Bytes(key) || ipv6Groups(key)) return false;
|
|
16659
|
+
if (hostsEntry(key, this.own) !== void 0) return true;
|
|
16660
|
+
return ((await this.hosts?.().catch(() => void 0))?.get(key)?.length ?? 0) > 0;
|
|
16661
|
+
}
|
|
16662
|
+
async reverse(address) {
|
|
16663
|
+
const v6 = ipv6Groups(address)?.join(":");
|
|
16664
|
+
const same2 = (a) => a === address || v6 !== void 0 && ipv6Groups(a)?.join(":") === v6;
|
|
16665
|
+
const file = await this.hosts?.().catch(() => void 0);
|
|
16666
|
+
for (const table of [file, this.builtin]) {
|
|
16667
|
+
for (const [name2, addresses] of table ?? []) if (addresses.some(same2)) return name2;
|
|
16668
|
+
}
|
|
16669
|
+
if (ipv4Bytes(address)?.[0] === 127) return "localhost";
|
|
16670
|
+
return void 0;
|
|
16671
|
+
}
|
|
16562
16672
|
async resolve(name2, family, blocking) {
|
|
16563
16673
|
const key = name2.toLowerCase().replace(/\.$/, "");
|
|
16564
|
-
const
|
|
16674
|
+
const local2 = hostsEntry(key, this.own);
|
|
16565
16675
|
if (ipv6Groups(key)) {
|
|
16566
|
-
const v4 = family !== 6 &&
|
|
16676
|
+
const v4 = family !== 6 && local2 ? [local2] : [];
|
|
16567
16677
|
return family === 4 ? v4 : [...v4, key];
|
|
16568
16678
|
}
|
|
16569
16679
|
const listed = this.hosts ? await this.fromFile(key, family) : void 0;
|
|
16570
16680
|
if (listed?.length) return listed;
|
|
16571
|
-
if (
|
|
16681
|
+
if (local2) {
|
|
16572
16682
|
const six = loopbackName(key, this.own) ? ["::1"] : [];
|
|
16573
|
-
return family === 6 ? six : family === 4 ? [
|
|
16683
|
+
return family === 6 ? six : family === 4 ? [local2] : [local2, ...six];
|
|
16574
16684
|
}
|
|
16575
16685
|
if (!this.uplink || key === "") return [];
|
|
16576
16686
|
const asked = this.uplink.traits.ipv6 ? family : 4;
|
|
@@ -17609,14 +17719,15 @@ var KernelDgram = class {
|
|
|
17609
17719
|
const max = familyOf(target.host) === 6 ? MAX_DATAGRAM_V6 : MAX_DATAGRAM_V4;
|
|
17610
17720
|
if (bytes.length > max) throw new KernelError("EMSGSIZE");
|
|
17611
17721
|
const where = this.route(target.host);
|
|
17612
|
-
const
|
|
17722
|
+
const local2 = this.bound();
|
|
17613
17723
|
if (where === "uplink") return this.sendUp(bytes, target);
|
|
17614
17724
|
const from = {
|
|
17615
17725
|
family: "inet",
|
|
17616
|
-
host:
|
|
17617
|
-
port:
|
|
17726
|
+
host: local2.host === "0.0.0.0" ? "127.0.0.1" : local2.host,
|
|
17727
|
+
port: local2.port
|
|
17618
17728
|
};
|
|
17619
|
-
const
|
|
17729
|
+
const dest = { family: "inet", host: canonicalHost(target.host), port: target.port };
|
|
17730
|
+
const delivered = this.net.deliverDgram(target.port, { bytes: bytes.slice(), from }, dest);
|
|
17620
17731
|
if (!delivered && this.peer && sameAddr(this.peer, target)) {
|
|
17621
17732
|
this.pending = "ECONNREFUSED";
|
|
17622
17733
|
this.changes.wake();
|
|
@@ -19213,8 +19324,8 @@ function clientFirstOf(message3) {
|
|
|
19213
19324
|
return m ? { header: m[1], bare: m[2] } : void 0;
|
|
19214
19325
|
}
|
|
19215
19326
|
var latinBytes = (text) => Uint8Array.from(text, (c) => c.charCodeAt(0));
|
|
19216
|
-
function channelOf(
|
|
19217
|
-
const head = latinBytes(
|
|
19327
|
+
function channelOf(header5, binding) {
|
|
19328
|
+
const head = latinBytes(header5);
|
|
19218
19329
|
const all = new Uint8Array(head.length + (binding?.length ?? 0));
|
|
19219
19330
|
all.set(head);
|
|
19220
19331
|
if (binding) all.set(binding, head.length);
|
|
@@ -19439,8 +19550,8 @@ function frame3(type, body) {
|
|
|
19439
19550
|
return out;
|
|
19440
19551
|
}
|
|
19441
19552
|
function pgLength(bytes, started) {
|
|
19442
|
-
const
|
|
19443
|
-
if (bytes.length <
|
|
19553
|
+
const header5 = started ? 5 : 4;
|
|
19554
|
+
if (bytes.length < header5) return void 0;
|
|
19444
19555
|
const length2 = int32(bytes, started ? 1 : 0);
|
|
19445
19556
|
return started ? 1 + length2 : length2;
|
|
19446
19557
|
}
|
|
@@ -19468,16 +19579,16 @@ function initial(message3) {
|
|
|
19468
19579
|
function int32Text(n) {
|
|
19469
19580
|
return String.fromCharCode(n >>> 24 & 255, n >>> 16 & 255, n >>> 8 & 255, n & 255);
|
|
19470
19581
|
}
|
|
19471
|
-
function serverHeader(
|
|
19472
|
-
if (
|
|
19473
|
-
if (
|
|
19474
|
-
if (
|
|
19582
|
+
function serverHeader(header5, server) {
|
|
19583
|
+
if (header5 === "n,,") return header5;
|
|
19584
|
+
if (header5 === "y,," && !server.plus) return header5;
|
|
19585
|
+
if (header5 === END_POINT && server.binding) return header5;
|
|
19475
19586
|
return server.plus && server.binding ? END_POINT : "n,,";
|
|
19476
19587
|
}
|
|
19477
|
-
function rewritten(first,
|
|
19588
|
+
function rewritten(first, header5) {
|
|
19478
19589
|
const parsed2 = clientFirstOf(first.data);
|
|
19479
|
-
if (!parsed2 || parsed2.header ===
|
|
19480
|
-
return { mechanism:
|
|
19590
|
+
if (!parsed2 || parsed2.header === header5) return first;
|
|
19591
|
+
return { mechanism: header5 === END_POINT ? PLUS : PLAIN, data: `${header5}${parsed2.bare}` };
|
|
19481
19592
|
}
|
|
19482
19593
|
var PgClient = class {
|
|
19483
19594
|
clientFirst;
|
|
@@ -20602,8 +20713,8 @@ async function datagram(req, proc) {
|
|
|
20602
20713
|
const ready2 = pollFile(dgram).readable;
|
|
20603
20714
|
if (req.nonblock && !ready2) throw new KernelError("EAGAIN");
|
|
20604
20715
|
const got = await dgram.receive(req.max, req.peek, ready2 ? void 0 : proc.blocking());
|
|
20605
|
-
const { bytes, from, truncated } = got;
|
|
20606
|
-
return { ok: true, kind: "bytes", bytes: encodeReceived({ bytes, truncated, ...from }) };
|
|
20716
|
+
const { bytes, from, truncated: truncated2 } = got;
|
|
20717
|
+
return { ok: true, kind: "bytes", bytes: encodeReceived({ bytes, truncated: truncated2, ...from }) };
|
|
20607
20718
|
}
|
|
20608
20719
|
async function unixDatagram(req, dgram, proc) {
|
|
20609
20720
|
if (req.op === "sock-sendto") {
|
|
@@ -20613,11 +20724,11 @@ async function unixDatagram(req, dgram, proc) {
|
|
|
20613
20724
|
const ready2 = pollFile(dgram).readable;
|
|
20614
20725
|
if (req.nonblock && !ready2) throw new KernelError("EAGAIN");
|
|
20615
20726
|
const got = await dgram.receive(req.max, req.peek, ready2 ? void 0 : proc.blocking());
|
|
20616
|
-
const { bytes, from, truncated } = got;
|
|
20727
|
+
const { bytes, from, truncated: truncated2 } = got;
|
|
20617
20728
|
return {
|
|
20618
20729
|
ok: true,
|
|
20619
20730
|
kind: "bytes",
|
|
20620
|
-
bytes: encodeReceived({ bytes, truncated, host: from.path, port: 0, unix: true })
|
|
20731
|
+
bytes: encodeReceived({ bytes, truncated: truncated2, host: from.path, port: 0, unix: true })
|
|
20621
20732
|
};
|
|
20622
20733
|
}
|
|
20623
20734
|
function domainOf(socket) {
|
|
@@ -23368,9 +23479,9 @@ var JsThreads = class {
|
|
|
23368
23479
|
const { control, port } = msg;
|
|
23369
23480
|
const tid = ++this.last;
|
|
23370
23481
|
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
23371
|
-
const
|
|
23482
|
+
const header5 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
23372
23483
|
const owned4 = new SharedArrayBuffer(4 * (1 + JS_THREAD_OWNED_FDS));
|
|
23373
|
-
if (this.frozen) Atomics.store(
|
|
23484
|
+
if (this.frozen) Atomics.store(header5, SAB_I_STOP, 1);
|
|
23374
23485
|
const clock = this.deps.clocks.thread(tid + 1, sab);
|
|
23375
23486
|
let ended = false;
|
|
23376
23487
|
const end = (code) => {
|
|
@@ -23378,7 +23489,7 @@ var JsThreads = class {
|
|
|
23378
23489
|
ended = true;
|
|
23379
23490
|
this.live.delete(tid);
|
|
23380
23491
|
this.headers.delete(tid);
|
|
23381
|
-
this.deps.wakes.delete(
|
|
23492
|
+
this.deps.wakes.delete(header5);
|
|
23382
23493
|
for (const [id2, token] of ops) {
|
|
23383
23494
|
void this.deps.dispatch({ op: "async-cancel", id: id2, token });
|
|
23384
23495
|
}
|
|
@@ -23428,8 +23539,8 @@ var JsThreads = class {
|
|
|
23428
23539
|
control.addEventListener("message", onControl);
|
|
23429
23540
|
control.start();
|
|
23430
23541
|
this.live.set(tid, end);
|
|
23431
|
-
this.headers.set(tid,
|
|
23432
|
-
this.deps.wakes.add(
|
|
23542
|
+
this.headers.set(tid, header5);
|
|
23543
|
+
this.deps.wakes.add(header5);
|
|
23433
23544
|
const init = {
|
|
23434
23545
|
...this.deps.init(sab, lane.lane),
|
|
23435
23546
|
type: JS_THREAD_INIT,
|
|
@@ -23449,9 +23560,9 @@ var JsThreads = class {
|
|
|
23449
23560
|
}
|
|
23450
23561
|
stopped(stopped) {
|
|
23451
23562
|
this.frozen = stopped;
|
|
23452
|
-
for (const
|
|
23453
|
-
Atomics.store(
|
|
23454
|
-
Atomics.notify(
|
|
23563
|
+
for (const header5 of this.headers.values()) {
|
|
23564
|
+
Atomics.store(header5, SAB_I_STOP, stopped ? 1 : 0);
|
|
23565
|
+
Atomics.notify(header5, SAB_I_STOP);
|
|
23455
23566
|
}
|
|
23456
23567
|
}
|
|
23457
23568
|
close() {
|
|
@@ -23496,13 +23607,13 @@ var Dying = class {
|
|
|
23496
23607
|
hard;
|
|
23497
23608
|
busy = 0;
|
|
23498
23609
|
finish;
|
|
23499
|
-
start(code, sig,
|
|
23610
|
+
start(code, sig, header5, process2, finish) {
|
|
23500
23611
|
if (this.ending) return;
|
|
23501
23612
|
this.ending = { code, sig };
|
|
23502
23613
|
this.finish = finish;
|
|
23503
23614
|
this.hard = setTimeout(finish, KILL_HARD_MS);
|
|
23504
23615
|
this.arm();
|
|
23505
|
-
Atomics.store(
|
|
23616
|
+
Atomics.store(header5, SAB_I_KILLED, code);
|
|
23506
23617
|
process2.die();
|
|
23507
23618
|
}
|
|
23508
23619
|
serve(req, work) {
|
|
@@ -23549,8 +23660,8 @@ function unblockedThread(threads, sig) {
|
|
|
23549
23660
|
}
|
|
23550
23661
|
return void 0;
|
|
23551
23662
|
}
|
|
23552
|
-
function unblocked(
|
|
23553
|
-
return Atomics.load(
|
|
23663
|
+
function unblocked(header5) {
|
|
23664
|
+
return Atomics.load(header5, SAB_I_SIGNALS) & ~Atomics.load(header5, SAB_I_BLOCKED);
|
|
23554
23665
|
}
|
|
23555
23666
|
function threadCall(process2, req, cancelled, block) {
|
|
23556
23667
|
return isWasmSyscall(req) ? process2.syscall(req, cancelled, block) : dispatchSyncFs(req);
|
|
@@ -23562,24 +23673,24 @@ function threadCancel(thread) {
|
|
|
23562
23673
|
return unblocked(thread.header) !== 0 ? AbortSignal.abort() : thread.interrupt.signal;
|
|
23563
23674
|
}
|
|
23564
23675
|
var asyncFanout = /* @__PURE__ */ new WeakMap();
|
|
23565
|
-
function notifiers(
|
|
23676
|
+
function notifiers(header5) {
|
|
23566
23677
|
return {
|
|
23567
23678
|
onPending(sig) {
|
|
23568
|
-
Atomics.or(
|
|
23569
|
-
Atomics.notify(
|
|
23679
|
+
Atomics.or(header5, SAB_I_SIGNALS, sigbit(sig));
|
|
23680
|
+
Atomics.notify(header5, SAB_I_SIGNALS);
|
|
23570
23681
|
},
|
|
23571
23682
|
onAsync() {
|
|
23572
|
-
for (const at of [
|
|
23683
|
+
for (const at of [header5, ...asyncFanout.get(header5) ?? []]) {
|
|
23573
23684
|
Atomics.add(at, SAB_I_ASYNC, 1);
|
|
23574
23685
|
Atomics.notify(at, SAB_I_ASYNC);
|
|
23575
23686
|
}
|
|
23576
23687
|
}
|
|
23577
23688
|
};
|
|
23578
23689
|
}
|
|
23579
|
-
function publishStops(process2,
|
|
23690
|
+
function publishStops(process2, header5) {
|
|
23580
23691
|
process2.onState((state) => {
|
|
23581
|
-
Atomics.store(
|
|
23582
|
-
Atomics.notify(
|
|
23692
|
+
Atomics.store(header5, SAB_I_STOP, state === "stopped" ? 1 : 0);
|
|
23693
|
+
Atomics.notify(header5, SAB_I_STOP);
|
|
23583
23694
|
});
|
|
23584
23695
|
}
|
|
23585
23696
|
function transferOf(opts, lane) {
|
|
@@ -23671,7 +23782,7 @@ function linksOf(opts) {
|
|
|
23671
23782
|
function clipboardName(opts) {
|
|
23672
23783
|
return opts.program.abi === "js" ? {} : { clipboardName: opts.argv0 };
|
|
23673
23784
|
}
|
|
23674
|
-
function processOptions(opts,
|
|
23785
|
+
function processOptions(opts, header5, hooks, created4) {
|
|
23675
23786
|
return {
|
|
23676
23787
|
...inherited(opts),
|
|
23677
23788
|
...opts.owners ? { owners: true } : {},
|
|
@@ -23710,16 +23821,16 @@ function processOptions(opts, header4, hooks, created4) {
|
|
|
23710
23821
|
watches: opts.watches,
|
|
23711
23822
|
onReap: opts.onReap,
|
|
23712
23823
|
resolver: opts.resolver,
|
|
23713
|
-
...notifiers(
|
|
23714
|
-
onTimer: (which) => void Atomics.or(
|
|
23715
|
-
hasPending: () => unblocked(
|
|
23824
|
+
...notifiers(header5),
|
|
23825
|
+
onTimer: (which) => void Atomics.or(header5, SAB_I_TIMERS, 1 << which),
|
|
23826
|
+
hasPending: () => unblocked(header5) !== 0 || Atomics.load(header5, SAB_I_TIMERS) !== 0,
|
|
23716
23827
|
raise: hooks.raise,
|
|
23717
23828
|
threadKill: hooks.threadKill,
|
|
23718
23829
|
unblockedThread: hooks.unblockedThread,
|
|
23719
23830
|
...hooks.exitNow ? { exitNow: hooks.exitNow } : {},
|
|
23720
23831
|
...hooks.exitSignal ? { exitSignal: hooks.exitSignal } : {},
|
|
23721
|
-
...opts.program.abi === "wasi" || opts.program.abi === "js" ? { pendingBits: () => Atomics.load(
|
|
23722
|
-
...opts.program.abi === "wasi" ? { blockedBits: () => Atomics.load(
|
|
23832
|
+
...opts.program.abi === "wasi" || opts.program.abi === "js" ? { pendingBits: () => Atomics.load(header5, SAB_I_SIGNALS) } : {},
|
|
23833
|
+
...opts.program.abi === "wasi" ? { blockedBits: () => Atomics.load(header5, SAB_I_BLOCKED) } : {}
|
|
23723
23834
|
};
|
|
23724
23835
|
}
|
|
23725
23836
|
function threadInit(opts, program, sab, cred, thread, main) {
|
|
@@ -23785,9 +23896,9 @@ async function crashReport(process2, onError, message3) {
|
|
|
23785
23896
|
function spawnWasmProcess(opts) {
|
|
23786
23897
|
const { promise: ready2, resolve: started } = readiness(opts.program.abi);
|
|
23787
23898
|
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
23788
|
-
const
|
|
23899
|
+
const header5 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
23789
23900
|
const blocked2 = opts.fork?.wasi?.blocked ?? opts.blocked;
|
|
23790
|
-
if (blocked2 && anyBlocked(blocked2) && opts.program.abi === "wasi") storeBlocked(
|
|
23901
|
+
if (blocked2 && anyBlocked(blocked2) && opts.program.abi === "wasi") storeBlocked(header5, blocked2);
|
|
23791
23902
|
const threadSignals = /* @__PURE__ */ new Map();
|
|
23792
23903
|
const created4 = new Created();
|
|
23793
23904
|
const process2 = new WasmProcess(
|
|
@@ -23795,7 +23906,7 @@ function spawnWasmProcess(opts) {
|
|
|
23795
23906
|
opts.fds,
|
|
23796
23907
|
processOptions(
|
|
23797
23908
|
opts,
|
|
23798
|
-
|
|
23909
|
+
header5,
|
|
23799
23910
|
{
|
|
23800
23911
|
raise: (sig, info) => signal(sig, info),
|
|
23801
23912
|
threadKill: (tid, sig) => killThread(threadSignals.get(tid), process2.signalMasks().caught, sig),
|
|
@@ -23808,7 +23919,7 @@ function spawnWasmProcess(opts) {
|
|
|
23808
23919
|
created4
|
|
23809
23920
|
)
|
|
23810
23921
|
);
|
|
23811
|
-
publishStops(process2,
|
|
23922
|
+
publishStops(process2, header5);
|
|
23812
23923
|
const holds2 = new HeldPaths();
|
|
23813
23924
|
opts.held?.add(holds2);
|
|
23814
23925
|
const token = holdingToken(opts, holds2, {
|
|
@@ -23829,7 +23940,7 @@ function spawnWasmProcess(opts) {
|
|
|
23829
23940
|
dispatch: clocks.timed(void 0, dispatch2)
|
|
23830
23941
|
});
|
|
23831
23942
|
const lane = opts.program.abi === "js" ? openLane(token, dispatch2) : void 0;
|
|
23832
|
-
const jsThreads = jsThreadsOf(opts, process2, token, dispatch2, clocks,
|
|
23943
|
+
const jsThreads = jsThreadsOf(opts, process2, token, dispatch2, clocks, header5);
|
|
23833
23944
|
const { promise: exited, resolve: settle } = Promise.withResolvers();
|
|
23834
23945
|
let done4 = false;
|
|
23835
23946
|
const crash = new CrashSlot((message3) => crashReport(process2, opts.onError, message3));
|
|
@@ -23928,7 +24039,7 @@ function spawnWasmProcess(opts) {
|
|
|
23928
24039
|
);
|
|
23929
24040
|
const terminate = (code, sig) => {
|
|
23930
24041
|
if (opts.program.abi !== "wasi" || done4) finish(code, sig);
|
|
23931
|
-
else dying.start(code, sig,
|
|
24042
|
+
else dying.start(code, sig, header5, process2, () => finish(code, sig));
|
|
23932
24043
|
};
|
|
23933
24044
|
const signal = (sig, info) => {
|
|
23934
24045
|
if (process2.signal(sig, info) === "terminate")
|
|
@@ -23943,16 +24054,16 @@ function spawnWasmProcess(opts) {
|
|
|
23943
24054
|
signal,
|
|
23944
24055
|
termsig: () => endedBy,
|
|
23945
24056
|
onState: (listener) => process2.onState(listener),
|
|
23946
|
-
memory: () => Atomics.load(
|
|
23947
|
-
...processViews(process2, opts,
|
|
24057
|
+
memory: () => Atomics.load(header5, SAB_I_MEMORY) * 65536,
|
|
24058
|
+
...processViews(process2, opts, header5),
|
|
23948
24059
|
writesBack: () => opts.program.abi === "wasi" && !done4,
|
|
23949
24060
|
...clockViews(clocks)
|
|
23950
24061
|
};
|
|
23951
24062
|
}
|
|
23952
|
-
function jsThreadsOf(opts, process2, token, dispatch2, clocks,
|
|
24063
|
+
function jsThreadsOf(opts, process2, token, dispatch2, clocks, header5) {
|
|
23953
24064
|
if (opts.program.abi !== "js") return void 0;
|
|
23954
24065
|
const wakes = /* @__PURE__ */ new Set();
|
|
23955
|
-
asyncFanout.set(
|
|
24066
|
+
asyncFanout.set(header5, wakes);
|
|
23956
24067
|
const threads = new JsThreads({
|
|
23957
24068
|
wakes,
|
|
23958
24069
|
cap: jsThreadCap(opts.env),
|
|
@@ -23967,10 +24078,10 @@ function jsThreadsOf(opts, process2, token, dispatch2, clocks, header4) {
|
|
|
23967
24078
|
process2.onState((state) => threads.stopped(state === "stopped"));
|
|
23968
24079
|
return threads;
|
|
23969
24080
|
}
|
|
23970
|
-
function processViews(process2, opts,
|
|
24081
|
+
function processViews(process2, opts, header5) {
|
|
23971
24082
|
return {
|
|
23972
24083
|
ignoredSignals: (fork) => process2.inheritable(fork),
|
|
23973
|
-
blockedSignals: () => opts.program.abi === "wasi" ? loadBlocked(
|
|
24084
|
+
blockedSignals: () => opts.program.abi === "wasi" ? loadBlocked(header5) : [0, 0],
|
|
23974
24085
|
signalMasks: () => process2.signalMasks(),
|
|
23975
24086
|
umask: () => process2.umask,
|
|
23976
24087
|
cred: () => copyCred(process2.cred)
|
|
@@ -24528,42 +24639,398 @@ function isMessage(data) {
|
|
|
24528
24639
|
return adopt !== null && Array.isArray(adopt.records) && Array.isArray(adopt.flocks);
|
|
24529
24640
|
}
|
|
24530
24641
|
|
|
24531
|
-
// src/kernel/net/
|
|
24532
|
-
var
|
|
24533
|
-
|
|
24534
|
-
|
|
24535
|
-
|
|
24536
|
-
|
|
24537
|
-
|
|
24538
|
-
|
|
24539
|
-
|
|
24540
|
-
|
|
24541
|
-
|
|
24542
|
-
|
|
24543
|
-
|
|
24642
|
+
// src/kernel/net/dns-stub.ts
|
|
24643
|
+
var DNS_PORT = 53;
|
|
24644
|
+
var DNS_STUB_ADDRESS = "127.0.0.53";
|
|
24645
|
+
var RESOLV_CONF_PATH = "/etc/resolv.conf";
|
|
24646
|
+
var RESOLV_CONF = `nameserver ${DNS_STUB_ADDRESS}
|
|
24647
|
+
options edns0
|
|
24648
|
+
`;
|
|
24649
|
+
var DNS_STUB_TTL = 30;
|
|
24650
|
+
var DNS_FORWARD_TIMEOUT_MS = 5e3;
|
|
24651
|
+
var DNS_TCP_IDLE_MS = 1e4;
|
|
24652
|
+
var DNS_TCP_MAX = 64;
|
|
24653
|
+
var DNS_UDP_INFLIGHT = 64;
|
|
24654
|
+
var TYPE_A = 1;
|
|
24655
|
+
var TYPE_PTR = 12;
|
|
24656
|
+
var TYPE_AAAA = 28;
|
|
24657
|
+
var TYPE_OPT = 41;
|
|
24658
|
+
var CLASS_IN = 1;
|
|
24659
|
+
var NOERROR = 0;
|
|
24660
|
+
var FORMERR = 1;
|
|
24661
|
+
var SERVFAIL = 2;
|
|
24662
|
+
var NXDOMAIN = 3;
|
|
24663
|
+
var NOTIMP = 4;
|
|
24664
|
+
var QR = 32768;
|
|
24665
|
+
var AA = 1024;
|
|
24666
|
+
var TC = 512;
|
|
24667
|
+
var RD = 256;
|
|
24668
|
+
var RA = 128;
|
|
24669
|
+
var CD = 16;
|
|
24670
|
+
var UDP_PLAIN = 512;
|
|
24671
|
+
var UDP_EDNS = 1232;
|
|
24672
|
+
var UDP_MAX = 4096;
|
|
24673
|
+
var DOH_MAX = 65535;
|
|
24674
|
+
var LOCAL_ZONES = ["localhost", "slicc.internal"];
|
|
24675
|
+
var MESSAGE = "application/dns-message";
|
|
24676
|
+
var u16 = (b, at) => b[at] << 8 | b[at + 1];
|
|
24677
|
+
function skipName(b, at) {
|
|
24678
|
+
let i = at;
|
|
24679
|
+
for (let hops = 0; hops < 128; hops++) {
|
|
24680
|
+
if (i >= b.length) return void 0;
|
|
24681
|
+
const len = b[i];
|
|
24682
|
+
if (len === 0) return i + 1;
|
|
24683
|
+
if ((len & 192) === 192) return i + 2 <= b.length ? i + 2 : void 0;
|
|
24684
|
+
if (len & 192) return void 0;
|
|
24685
|
+
i += len + 1;
|
|
24686
|
+
}
|
|
24687
|
+
return void 0;
|
|
24688
|
+
}
|
|
24689
|
+
function readName(b, at) {
|
|
24690
|
+
const labels = [];
|
|
24691
|
+
let i = at;
|
|
24692
|
+
let size = 0;
|
|
24693
|
+
for (; ; ) {
|
|
24694
|
+
if (i >= b.length) return void 0;
|
|
24695
|
+
const len = b[i];
|
|
24696
|
+
if (len === 0) break;
|
|
24697
|
+
if (len & 192) return void 0;
|
|
24698
|
+
size += len + 1;
|
|
24699
|
+
if (size > 254 || i + 1 + len > b.length) return void 0;
|
|
24700
|
+
labels.push(new TextDecoder().decode(b.subarray(i + 1, i + 1 + len)));
|
|
24701
|
+
i += len + 1;
|
|
24702
|
+
}
|
|
24703
|
+
return { name: labels.join(".").toLowerCase(), end: i + 1 };
|
|
24704
|
+
}
|
|
24705
|
+
function parseQuery(b) {
|
|
24706
|
+
if (b.length < 12) return void 0;
|
|
24707
|
+
const id2 = u16(b, 0);
|
|
24708
|
+
const flags2 = u16(b, 2);
|
|
24709
|
+
if (flags2 & QR) return void 0;
|
|
24710
|
+
if (flags2 >> 11 & 15) return { ok: false, id: id2, flags: flags2, rcode: NOTIMP };
|
|
24711
|
+
if (u16(b, 4) !== 1) return { ok: false, id: id2, flags: flags2, rcode: FORMERR };
|
|
24712
|
+
const read = readName(b, 12);
|
|
24713
|
+
if (!read || read.end + 4 > b.length) return { ok: false, id: id2, flags: flags2, rcode: FORMERR };
|
|
24714
|
+
const type = u16(b, read.end);
|
|
24715
|
+
const klass = u16(b, read.end + 2);
|
|
24716
|
+
const end = read.end + 4;
|
|
24717
|
+
let edns;
|
|
24718
|
+
let at = end;
|
|
24719
|
+
const records = u16(b, 6) + u16(b, 8) + u16(b, 10);
|
|
24720
|
+
for (let n = 0; n < records; n++) {
|
|
24721
|
+
const after = skipName(b, at);
|
|
24722
|
+
if (after === void 0 || after + 10 > b.length)
|
|
24723
|
+
return { ok: false, id: id2, flags: flags2, rcode: FORMERR };
|
|
24724
|
+
if (u16(b, after) === TYPE_OPT) edns = Math.max(UDP_PLAIN, u16(b, after + 2));
|
|
24725
|
+
at = after + 10 + u16(b, after + 8);
|
|
24726
|
+
if (at > b.length) return { ok: false, id: id2, flags: flags2, rcode: FORMERR };
|
|
24727
|
+
}
|
|
24728
|
+
return { ok: true, question: { id: id2, flags: flags2, name: read.name, type, klass, end, edns } };
|
|
24729
|
+
}
|
|
24730
|
+
function encodeName(name2) {
|
|
24731
|
+
const out = [];
|
|
24732
|
+
for (const label of name2.split(".").filter(Boolean)) {
|
|
24733
|
+
const bytes = new TextEncoder().encode(label);
|
|
24734
|
+
out.push(bytes.length, ...bytes);
|
|
24735
|
+
}
|
|
24736
|
+
out.push(0);
|
|
24737
|
+
return out;
|
|
24738
|
+
}
|
|
24739
|
+
function header2(id2, flags2, counts) {
|
|
24740
|
+
const out = [id2 >> 8, id2 & 255, flags2 >> 8, flags2 & 255];
|
|
24741
|
+
for (const c of counts) out.push(c >> 8, c & 255);
|
|
24742
|
+
return out;
|
|
24743
|
+
}
|
|
24744
|
+
function opt() {
|
|
24745
|
+
return [0, 0, TYPE_OPT, UDP_EDNS >> 8, UDP_EDNS & 255, 0, 0, 0, 0, 0, 0];
|
|
24746
|
+
}
|
|
24747
|
+
function record(type, rdata) {
|
|
24748
|
+
const ttl = DNS_STUB_TTL;
|
|
24749
|
+
return [
|
|
24750
|
+
192,
|
|
24751
|
+
12,
|
|
24752
|
+
type >> 8,
|
|
24753
|
+
type & 255,
|
|
24754
|
+
0,
|
|
24755
|
+
CLASS_IN,
|
|
24756
|
+
ttl >>> 24 & 255,
|
|
24757
|
+
ttl >>> 16 & 255,
|
|
24758
|
+
ttl >>> 8 & 255,
|
|
24759
|
+
ttl & 255,
|
|
24760
|
+
rdata.length >> 8,
|
|
24761
|
+
rdata.length & 255,
|
|
24762
|
+
...rdata
|
|
24763
|
+
];
|
|
24764
|
+
}
|
|
24765
|
+
function replyFlags(query, rcode, aa) {
|
|
24766
|
+
return QR | query & 30720 | (aa ? AA : 0) | query & RD | RA | query & CD | rcode;
|
|
24767
|
+
}
|
|
24768
|
+
function answers(reply, q) {
|
|
24769
|
+
if (reply.length < 12 || !(u16(reply, 2) & QR) || u16(reply, 4) !== 1) return false;
|
|
24770
|
+
const read = readName(reply, 12);
|
|
24771
|
+
if (!read || read.end + 4 > reply.length) return false;
|
|
24772
|
+
return read.name === q.name && u16(reply, read.end) === q.type && u16(reply, read.end + 2) === q.klass;
|
|
24773
|
+
}
|
|
24774
|
+
function errorReply(id2, flags2, rcode) {
|
|
24775
|
+
return new Uint8Array(header2(id2, replyFlags(flags2, rcode, false), [0, 0, 0, 0]));
|
|
24776
|
+
}
|
|
24777
|
+
function answerReply(query, q, rcode, answers2, aa) {
|
|
24778
|
+
const extra = q.edns !== void 0 ? [opt()] : [];
|
|
24779
|
+
return new Uint8Array([
|
|
24780
|
+
...header2(q.id, replyFlags(q.flags, rcode, aa), [1, answers2.length, 0, extra.length]),
|
|
24781
|
+
...query.subarray(12, q.end),
|
|
24782
|
+
...answers2.flat(),
|
|
24783
|
+
...extra.flat()
|
|
24784
|
+
]);
|
|
24785
|
+
}
|
|
24786
|
+
function truncated(reply, q, query) {
|
|
24787
|
+
const limit = q.edns !== void 0 ? Math.min(q.edns, UDP_MAX) : UDP_PLAIN;
|
|
24788
|
+
if (reply.length <= limit) return reply;
|
|
24789
|
+
const flags2 = u16(reply, 2) | TC;
|
|
24790
|
+
const extra = q.edns !== void 0 ? [opt()] : [];
|
|
24791
|
+
return new Uint8Array([
|
|
24792
|
+
...header2(q.id, flags2, [1, 0, 0, extra.length]),
|
|
24793
|
+
...query.subarray(12, q.end),
|
|
24794
|
+
...extra.flat()
|
|
24795
|
+
]);
|
|
24796
|
+
}
|
|
24797
|
+
function ipv6Text(groups) {
|
|
24798
|
+
return groups.map((g) => g.toString(16)).join(":");
|
|
24799
|
+
}
|
|
24800
|
+
function reverseAddress(name2) {
|
|
24801
|
+
if (name2.endsWith(".in-addr.arpa")) {
|
|
24802
|
+
const parts2 = name2.slice(0, -".in-addr.arpa".length).split(".");
|
|
24803
|
+
if (parts2.length !== 4) return void 0;
|
|
24804
|
+
const text = parts2.reverse().join(".");
|
|
24805
|
+
return ipv4Bytes(text) ? text.split(".").map(Number).join(".") : void 0;
|
|
24806
|
+
}
|
|
24807
|
+
if (name2.endsWith(".ip6.arpa")) {
|
|
24808
|
+
const nibbles = name2.slice(0, -".ip6.arpa".length).split(".");
|
|
24809
|
+
if (nibbles.length !== 32 || !nibbles.every((n) => /^[0-9a-f]$/.test(n))) return void 0;
|
|
24810
|
+
const hex4 = nibbles.reverse().join("");
|
|
24811
|
+
const groups = Array.from(
|
|
24812
|
+
{ length: 8 },
|
|
24813
|
+
(_, i) => Number.parseInt(hex4.slice(i * 4, i * 4 + 4), 16)
|
|
24814
|
+
);
|
|
24815
|
+
return ipv6Text(groups);
|
|
24816
|
+
}
|
|
24817
|
+
return void 0;
|
|
24818
|
+
}
|
|
24819
|
+
function local(name2) {
|
|
24820
|
+
return LOCAL_ZONES.some((zone) => name2 === zone || name2.endsWith(`.${zone}`));
|
|
24821
|
+
}
|
|
24822
|
+
function literal(name2) {
|
|
24823
|
+
return ipv4Bytes(name2) !== void 0 || ipv6Groups(name2) !== void 0;
|
|
24824
|
+
}
|
|
24825
|
+
function addressData(address, type) {
|
|
24826
|
+
if (type === TYPE_A) return ipv4Bytes(address);
|
|
24827
|
+
const groups = type === TYPE_AAAA ? ipv6Groups(address) : void 0;
|
|
24828
|
+
return groups?.flatMap((g) => [g >> 8, g & 255]);
|
|
24829
|
+
}
|
|
24830
|
+
var DnsStub = class {
|
|
24831
|
+
resolver;
|
|
24832
|
+
forwarder;
|
|
24833
|
+
timeoutMs;
|
|
24834
|
+
constructor(options) {
|
|
24835
|
+
this.resolver = options.resolver;
|
|
24836
|
+
this.forwarder = options.forward;
|
|
24837
|
+
this.timeoutMs = options.timeoutMs ?? DNS_FORWARD_TIMEOUT_MS;
|
|
24838
|
+
}
|
|
24839
|
+
async answer(query, udp) {
|
|
24840
|
+
const parsed2 = parseQuery(query);
|
|
24841
|
+
if (!parsed2) return void 0;
|
|
24842
|
+
if (!parsed2.ok) return errorReply(parsed2.id, parsed2.flags, parsed2.rcode);
|
|
24843
|
+
const q = parsed2.question;
|
|
24844
|
+
const reply = await this.reply(query, q).catch(
|
|
24845
|
+
() => answerReply(query, q, SERVFAIL, [], false)
|
|
24846
|
+
);
|
|
24847
|
+
return udp ? truncated(reply, q, query) : reply;
|
|
24848
|
+
}
|
|
24849
|
+
async reply(query, q) {
|
|
24850
|
+
if (q.klass !== CLASS_IN || literal(q.name)) return this.forward(query, q);
|
|
24851
|
+
if (q.type === TYPE_PTR) {
|
|
24852
|
+
const address = reverseAddress(q.name);
|
|
24853
|
+
const name2 = address !== void 0 ? await this.reverse(address) : void 0;
|
|
24854
|
+
if (name2 !== void 0)
|
|
24855
|
+
return answerReply(query, q, NOERROR, [record(TYPE_PTR, encodeName(name2))], true);
|
|
24856
|
+
return this.forward(query, q);
|
|
24857
|
+
}
|
|
24858
|
+
if (q.type === TYPE_A || q.type === TYPE_AAAA) {
|
|
24859
|
+
const addresses = q.name === "" ? [] : await this.lookup(q.name);
|
|
24860
|
+
const answers2 = addresses.flatMap((a) => {
|
|
24861
|
+
const data = addressData(a, q.type);
|
|
24862
|
+
return data ? [record(q.type, data)] : [];
|
|
24863
|
+
});
|
|
24864
|
+
if (answers2.length > 0 || local(q.name) || await this.known(q.name)) {
|
|
24865
|
+
const rcode = addresses.length > 0 ? NOERROR : NXDOMAIN;
|
|
24866
|
+
return answerReply(query, q, rcode, answers2, local(q.name));
|
|
24867
|
+
}
|
|
24868
|
+
return this.forward(query, q);
|
|
24544
24869
|
}
|
|
24870
|
+
if (await this.known(q.name)) return answerReply(query, q, NOERROR, [], true);
|
|
24871
|
+
if (local(q.name)) {
|
|
24872
|
+
const there = (await this.lookup(q.name)).length > 0;
|
|
24873
|
+
return answerReply(query, q, there ? NOERROR : NXDOMAIN, [], true);
|
|
24874
|
+
}
|
|
24875
|
+
return this.forward(query, q);
|
|
24545
24876
|
}
|
|
24546
|
-
|
|
24877
|
+
lookup(name2) {
|
|
24878
|
+
return this.resolver.resolve(name2, 0).catch(() => []);
|
|
24879
|
+
}
|
|
24880
|
+
known(name2) {
|
|
24881
|
+
return this.resolver.known(name2).catch(() => false);
|
|
24882
|
+
}
|
|
24883
|
+
reverse(address) {
|
|
24884
|
+
return this.resolver.reverse(address).catch(() => void 0);
|
|
24885
|
+
}
|
|
24886
|
+
async forward(query, q) {
|
|
24887
|
+
if (!this.forwarder) return answerReply(query, q, SERVFAIL, [], false);
|
|
24888
|
+
const asked = query.slice();
|
|
24889
|
+
asked[0] = 0;
|
|
24890
|
+
asked[1] = 0;
|
|
24891
|
+
const got = await this.forwarder(asked, AbortSignal.timeout(this.timeoutMs)).catch(
|
|
24892
|
+
() => void 0
|
|
24893
|
+
);
|
|
24894
|
+
if (!got || !answers(got, q)) return answerReply(query, q, SERVFAIL, [], false);
|
|
24895
|
+
const reply = got.slice();
|
|
24896
|
+
reply[0] = q.id >> 8;
|
|
24897
|
+
reply[1] = q.id & 255;
|
|
24898
|
+
return reply;
|
|
24899
|
+
}
|
|
24900
|
+
};
|
|
24901
|
+
async function collect(body, max) {
|
|
24902
|
+
const parts2 = [];
|
|
24903
|
+
let size = 0;
|
|
24904
|
+
for await (const part of body) {
|
|
24905
|
+
size += part.length;
|
|
24906
|
+
if (size > max) return void 0;
|
|
24907
|
+
parts2.push(part);
|
|
24908
|
+
}
|
|
24909
|
+
const out = new Uint8Array(size);
|
|
24910
|
+
let at = 0;
|
|
24911
|
+
for (const part of parts2) {
|
|
24912
|
+
out.set(part, at);
|
|
24913
|
+
at += part.length;
|
|
24914
|
+
}
|
|
24915
|
+
return out;
|
|
24547
24916
|
}
|
|
24548
|
-
function
|
|
24549
|
-
|
|
24550
|
-
|
|
24551
|
-
|
|
24552
|
-
|
|
24553
|
-
|
|
24554
|
-
|
|
24555
|
-
|
|
24917
|
+
function dohForward(transport, url) {
|
|
24918
|
+
return async (query, signal) => {
|
|
24919
|
+
const res = await transport.fetch({
|
|
24920
|
+
url,
|
|
24921
|
+
method: "POST",
|
|
24922
|
+
headers: [
|
|
24923
|
+
["content-type", MESSAGE],
|
|
24924
|
+
["accept", MESSAGE]
|
|
24925
|
+
],
|
|
24926
|
+
body: query,
|
|
24927
|
+
signal
|
|
24928
|
+
});
|
|
24929
|
+
const type = res.headers.find(([k]) => k.toLowerCase() === "content-type")?.[1] ?? "";
|
|
24930
|
+
if (res.status !== 200 || type.split(";")[0].trim().toLowerCase() !== MESSAGE) {
|
|
24931
|
+
await res.cancel().catch(() => void 0);
|
|
24556
24932
|
return void 0;
|
|
24557
24933
|
}
|
|
24558
|
-
|
|
24559
|
-
|
|
24560
|
-
|
|
24561
|
-
|
|
24562
|
-
|
|
24563
|
-
|
|
24564
|
-
|
|
24934
|
+
return collect(res.body, DOH_MAX);
|
|
24935
|
+
};
|
|
24936
|
+
}
|
|
24937
|
+
function uplinkForward(uplink, server) {
|
|
24938
|
+
return async (query, signal) => {
|
|
24939
|
+
const conn = await uplink.dial({ network: "tcp", host: server, port: DNS_PORT, signal });
|
|
24940
|
+
const stop = () => conn.close();
|
|
24941
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
24942
|
+
try {
|
|
24943
|
+
await conn.write(new Uint8Array([query.length >> 8, query.length & 255, ...query]));
|
|
24944
|
+
let got = new Uint8Array();
|
|
24945
|
+
for (; ; ) {
|
|
24946
|
+
if (got.length >= 2 && got.length >= 2 + u16(got, 0)) return got.slice(2, 2 + u16(got, 0));
|
|
24947
|
+
const piece = await conn.read();
|
|
24948
|
+
if (!piece) return void 0;
|
|
24949
|
+
const next3 = new Uint8Array(got.length + piece.length);
|
|
24950
|
+
next3.set(got);
|
|
24951
|
+
next3.set(piece, got.length);
|
|
24952
|
+
got = next3;
|
|
24953
|
+
}
|
|
24954
|
+
} finally {
|
|
24955
|
+
signal.removeEventListener("abort", stop);
|
|
24956
|
+
conn.close();
|
|
24957
|
+
}
|
|
24565
24958
|
};
|
|
24566
24959
|
}
|
|
24960
|
+
function dnsForward(uplink, transport, doh) {
|
|
24961
|
+
const server = uplink?.nameserver;
|
|
24962
|
+
if (uplink && server && (ipv4Bytes(server) || ipv6Groups(server)))
|
|
24963
|
+
return uplinkForward(uplink, server);
|
|
24964
|
+
return typeof doh === "string" ? dohForward(transport, doh) : void 0;
|
|
24965
|
+
}
|
|
24966
|
+
function kernelDnsStub(resolver, transport, uplink, doh) {
|
|
24967
|
+
return new DnsStub({ resolver, forward: dnsForward(uplink, transport, doh) });
|
|
24968
|
+
}
|
|
24969
|
+
async function readExactly(conn, size, signal) {
|
|
24970
|
+
const out = new Uint8Array(size);
|
|
24971
|
+
let at = 0;
|
|
24972
|
+
while (at < size) {
|
|
24973
|
+
const piece = await conn.read(size - at, signal);
|
|
24974
|
+
if (piece.length === 0) return void 0;
|
|
24975
|
+
out.set(piece, at);
|
|
24976
|
+
at += piece.length;
|
|
24977
|
+
}
|
|
24978
|
+
return out;
|
|
24979
|
+
}
|
|
24980
|
+
async function serveTcp(stub, conn) {
|
|
24981
|
+
try {
|
|
24982
|
+
for (; ; ) {
|
|
24983
|
+
const idle2 = AbortSignal.timeout(DNS_TCP_IDLE_MS);
|
|
24984
|
+
const size = await readExactly(conn, 2, idle2);
|
|
24985
|
+
if (!size) return;
|
|
24986
|
+
const query = await readExactly(conn, u16(size, 0), idle2);
|
|
24987
|
+
if (!query) return;
|
|
24988
|
+
const reply = await stub.answer(query, false);
|
|
24989
|
+
if (!reply) return;
|
|
24990
|
+
const framed = new Uint8Array([reply.length >> 8, reply.length & 255, ...reply]);
|
|
24991
|
+
const sent = await conn.write(framed, AbortSignal.timeout(DNS_TCP_IDLE_MS));
|
|
24992
|
+
if (sent < framed.length) return;
|
|
24993
|
+
}
|
|
24994
|
+
} catch {
|
|
24995
|
+
return;
|
|
24996
|
+
} finally {
|
|
24997
|
+
conn.close();
|
|
24998
|
+
}
|
|
24999
|
+
}
|
|
25000
|
+
function enableDnsStub(net, stub) {
|
|
25001
|
+
const at = { family: "inet", host: "127.0.0.1", port: DNS_PORT };
|
|
25002
|
+
net.reserve(DNS_PORT);
|
|
25003
|
+
net.kernelOnly(DNS_PORT, true);
|
|
25004
|
+
net.activate(at, () => {
|
|
25005
|
+
const listener = net.listen(at);
|
|
25006
|
+
const open = /* @__PURE__ */ new Set();
|
|
25007
|
+
void (async () => {
|
|
25008
|
+
for (; ; ) {
|
|
25009
|
+
const conn = await listener.accept().catch(() => void 0);
|
|
25010
|
+
if (!conn) return;
|
|
25011
|
+
if (open.size >= DNS_TCP_MAX) {
|
|
25012
|
+
conn.close();
|
|
25013
|
+
continue;
|
|
25014
|
+
}
|
|
25015
|
+
open.add(conn);
|
|
25016
|
+
void serveTcp(stub, conn).finally(() => open.delete(conn));
|
|
25017
|
+
}
|
|
25018
|
+
})();
|
|
25019
|
+
});
|
|
25020
|
+
let inflight = 0;
|
|
25021
|
+
net.serveDgram(DNS_PORT, (datagram2, to) => {
|
|
25022
|
+
if (inflight >= DNS_UDP_INFLIGHT) return;
|
|
25023
|
+
inflight++;
|
|
25024
|
+
void stub.answer(datagram2.bytes, true).then(
|
|
25025
|
+
(reply) => {
|
|
25026
|
+
if (!reply) return;
|
|
25027
|
+
const from = { family: "inet", host: to.host, port: DNS_PORT };
|
|
25028
|
+
net.deliverDgram(datagram2.from.port, { bytes: reply, from });
|
|
25029
|
+
},
|
|
25030
|
+
() => void 0
|
|
25031
|
+
).finally(() => inflight--);
|
|
25032
|
+
});
|
|
25033
|
+
}
|
|
24567
25034
|
|
|
24568
25035
|
// src/kernel/net/redirect-hops.ts
|
|
24569
25036
|
var HELD_MS = 3e4;
|
|
@@ -24571,13 +25038,13 @@ var HELD_MAX = 64;
|
|
|
24571
25038
|
var HELD_PER_OWNER = 8;
|
|
24572
25039
|
var MATCHED = ["range", "if-none-match", "if-modified-since", "if-range", "accept-encoding"];
|
|
24573
25040
|
var KERNEL = -1;
|
|
24574
|
-
function
|
|
25041
|
+
function header3(headers, name2) {
|
|
24575
25042
|
const values = headers.filter(([n]) => n.toLowerCase() === name2).map(([, v]) => v);
|
|
24576
25043
|
return values.length > 0 ? values.join(", ") : void 0;
|
|
24577
25044
|
}
|
|
24578
25045
|
function fingerprint(headers) {
|
|
24579
|
-
const fields = MATCHED.map((name2) =>
|
|
24580
|
-
return JSON.stringify([...fields,
|
|
25046
|
+
const fields = MATCHED.map((name2) => header3(headers, name2) ?? "");
|
|
25047
|
+
return JSON.stringify([...fields, header3(headers, "authorization") !== void 0]);
|
|
24581
25048
|
}
|
|
24582
25049
|
function unauthorized(print) {
|
|
24583
25050
|
return JSON.stringify([...JSON.parse(print).slice(0, -1), false]);
|
|
@@ -24620,7 +25087,7 @@ function replayingHops(inner, heldMs = HELD_MS) {
|
|
|
24620
25087
|
};
|
|
24621
25088
|
const replay = (chain2) => {
|
|
24622
25089
|
const [hop, ...rest2] = chain2.hops;
|
|
24623
|
-
const location = hop &&
|
|
25090
|
+
const location = hop && header3(hop.headers, "location");
|
|
24624
25091
|
if (!hop || location === void 0) return chain2.final;
|
|
24625
25092
|
const target = new URL(location, hop.url);
|
|
24626
25093
|
target.hash = "";
|
|
@@ -24745,7 +25212,7 @@ function materializable(req) {
|
|
|
24745
25212
|
if (req.shellGrants !== true && !isStrings(req.names)) return false;
|
|
24746
25213
|
return isStrings(req.argv) && typeof req.path === "string" && typeof req.cwd === "string";
|
|
24747
25214
|
}
|
|
24748
|
-
function
|
|
25215
|
+
function errorReply2(code, message3) {
|
|
24749
25216
|
return { v: 1, error: { code, message: message3 } };
|
|
24750
25217
|
}
|
|
24751
25218
|
function isRecord(value2) {
|
|
@@ -24757,9 +25224,9 @@ function serialized(reply) {
|
|
|
24757
25224
|
const text = JSON.stringify(reply);
|
|
24758
25225
|
plain3 = text === void 0 ? void 0 : JSON.parse(text);
|
|
24759
25226
|
} catch (err) {
|
|
24760
|
-
return JSON.stringify(
|
|
25227
|
+
return JSON.stringify(errorReply2("EIO", lineOf2(err)));
|
|
24761
25228
|
}
|
|
24762
|
-
if (!isRecord(plain3)) return JSON.stringify(
|
|
25229
|
+
if (!isRecord(plain3)) return JSON.stringify(errorReply2("EIO", "the vault gave no reply"));
|
|
24763
25230
|
const { v: _, ...rest2 } = plain3;
|
|
24764
25231
|
return JSON.stringify({ v: 1, ...rest2 });
|
|
24765
25232
|
}
|
|
@@ -24807,18 +25274,18 @@ var SealedChannel = class {
|
|
|
24807
25274
|
}
|
|
24808
25275
|
async answer(req, signal) {
|
|
24809
25276
|
const hook = this.broker.hook;
|
|
24810
|
-
if (!hook) return
|
|
25277
|
+
if (!hook) return errorReply2("ENOTCONN", "no vault is connected");
|
|
24811
25278
|
const stopped = new Promise((resolve2) => {
|
|
24812
25279
|
signal.addEventListener("abort", () => resolve2(void 0), { once: true });
|
|
24813
25280
|
});
|
|
24814
25281
|
if (signal.aborted) return void 0;
|
|
24815
25282
|
const asked = Promise.resolve().then(() => hook(req, { signal })).then(
|
|
24816
|
-
(reply2) => isRecord(reply2) ? reply2 :
|
|
24817
|
-
(err) =>
|
|
25283
|
+
(reply2) => isRecord(reply2) ? reply2 : errorReply2("EIO", "the vault gave no reply"),
|
|
25284
|
+
(err) => errorReply2("EIO", lineOf2(err))
|
|
24818
25285
|
);
|
|
24819
25286
|
const reply = await Promise.race([asked, stopped]);
|
|
24820
25287
|
if (!signal.aborted) return reply;
|
|
24821
|
-
return signal.reason === "timeout" ?
|
|
25288
|
+
return signal.reason === "timeout" ? errorReply2("ETIMEDOUT", "the vault did not answer within 10 s") : void 0;
|
|
24822
25289
|
}
|
|
24823
25290
|
drop() {
|
|
24824
25291
|
this.reply?.fill(0);
|
|
@@ -27232,6 +27699,10 @@ function dataModuleUrl(source) {
|
|
|
27232
27699
|
return { url: `data:text/javascript;base64,${btoa(binary2)}`, revoke: () => {
|
|
27233
27700
|
} };
|
|
27234
27701
|
}
|
|
27702
|
+
function describe(req, tty) {
|
|
27703
|
+
const exe = req.exe === void 0 ? {} : { exe: req.exe };
|
|
27704
|
+
return { argv: [req.argv0, ...req.args], tty, started: Date.now(), ...exe };
|
|
27705
|
+
}
|
|
27235
27706
|
function linksOf2(req) {
|
|
27236
27707
|
return req.links === void 0 ? {} : { links: req.links };
|
|
27237
27708
|
}
|
|
@@ -27253,6 +27724,7 @@ var LAYOUT = [
|
|
|
27253
27724
|
["/etc", 493],
|
|
27254
27725
|
[PASSWD, 420],
|
|
27255
27726
|
[GROUP, 420],
|
|
27727
|
+
[RESOLV_CONF_PATH, 420],
|
|
27256
27728
|
["/usr", 493],
|
|
27257
27729
|
["/usr/local", 493]
|
|
27258
27730
|
];
|
|
@@ -27595,6 +28067,10 @@ var Launcher = class {
|
|
|
27595
28067
|
roots: packageTlsRoots(this.verifiedFs(options.fs), this.modulesDir),
|
|
27596
28068
|
ca: this.ca
|
|
27597
28069
|
});
|
|
28070
|
+
enableDnsStub(
|
|
28071
|
+
this.net,
|
|
28072
|
+
kernelDnsStub(this.resolver, this.transport, options.uplink, options.doh)
|
|
28073
|
+
);
|
|
27598
28074
|
enableCdp(this.net, this.cdp);
|
|
27599
28075
|
this.facades.enable(this.net);
|
|
27600
28076
|
const fs = this.commandFs(this.base);
|
|
@@ -27682,10 +28158,10 @@ var Launcher = class {
|
|
|
27682
28158
|
ready: () => this.fstab,
|
|
27683
28159
|
lookup: (name2) => this.users.lookup(name2),
|
|
27684
28160
|
watch: async (paths, notify) => {
|
|
27685
|
-
const
|
|
28161
|
+
const local2 = this.watchers.watch(paths, { recursive: true }, () => notify());
|
|
27686
28162
|
const remote = await this.watchFiles(paths, notify);
|
|
27687
28163
|
return () => {
|
|
27688
|
-
|
|
28164
|
+
local2();
|
|
27689
28165
|
remote();
|
|
27690
28166
|
};
|
|
27691
28167
|
},
|
|
@@ -27871,7 +28347,7 @@ var Launcher = class {
|
|
|
27871
28347
|
abi: "wasi",
|
|
27872
28348
|
glue,
|
|
27873
28349
|
wasm: glue,
|
|
27874
|
-
argv0
|
|
28350
|
+
argv0,
|
|
27875
28351
|
...asked
|
|
27876
28352
|
};
|
|
27877
28353
|
}
|
|
@@ -28413,7 +28889,18 @@ var Launcher = class {
|
|
|
28413
28889
|
const handle = await this.admitted(
|
|
28414
28890
|
program.abi !== "js",
|
|
28415
28891
|
req.fds,
|
|
28416
|
-
(fds, quietOom) => this.start({
|
|
28892
|
+
(fds, quietOom) => this.start({
|
|
28893
|
+
...req,
|
|
28894
|
+
fds,
|
|
28895
|
+
quietOom,
|
|
28896
|
+
cwd,
|
|
28897
|
+
program,
|
|
28898
|
+
argv0: target.argv0,
|
|
28899
|
+
exe: target.copy ?? target.glue,
|
|
28900
|
+
args,
|
|
28901
|
+
env,
|
|
28902
|
+
cwdSlot
|
|
28903
|
+
})
|
|
28417
28904
|
).finally(() => this.cwds.release(cwdSlot));
|
|
28418
28905
|
void handle.exited.finally(done4);
|
|
28419
28906
|
return handle;
|
|
@@ -28605,11 +29092,7 @@ var Launcher = class {
|
|
|
28605
29092
|
if (req.pgid !== void 0) this.jobs.join(pid, req.pgid);
|
|
28606
29093
|
if (req.group === "lead") this.jobs.lead(pid);
|
|
28607
29094
|
if (req.group === "session") this.jobs.setsid(pid);
|
|
28608
|
-
this.described.set(pid,
|
|
28609
|
-
argv: [req.argv0, ...req.args],
|
|
28610
|
-
tty: terminal?.name ?? null,
|
|
28611
|
-
started: Date.now()
|
|
28612
|
-
});
|
|
29095
|
+
this.described.set(pid, describe(req, terminal?.name ?? null));
|
|
28613
29096
|
handle.onState(
|
|
28614
29097
|
(state) => state === "stopped" ? this.stopped.add(pid) : this.stopped.delete(pid)
|
|
28615
29098
|
);
|
|
@@ -29217,6 +29700,19 @@ var Launcher = class {
|
|
|
29217
29700
|
inUse(path) {
|
|
29218
29701
|
return [...this.openFiles].some((nodes) => nodes.holds(path)) || heldUnder(this.held, path);
|
|
29219
29702
|
}
|
|
29703
|
+
async resolvConf() {
|
|
29704
|
+
if (isProtected(this.prefixes, RESOLV_CONF_PATH)) return;
|
|
29705
|
+
try {
|
|
29706
|
+
const there = await this.base.lstat(RESOLV_CONF_PATH).then(
|
|
29707
|
+
() => true,
|
|
29708
|
+
() => false
|
|
29709
|
+
);
|
|
29710
|
+
if (there) return;
|
|
29711
|
+
await this.base.writeFile(RESOLV_CONF_PATH, RESOLV_CONF);
|
|
29712
|
+
} catch {
|
|
29713
|
+
return;
|
|
29714
|
+
}
|
|
29715
|
+
}
|
|
29220
29716
|
async stampLayout() {
|
|
29221
29717
|
const layout = [
|
|
29222
29718
|
...LAYOUT,
|
|
@@ -29352,6 +29848,7 @@ var Launcher = class {
|
|
|
29352
29848
|
await this.mountShm();
|
|
29353
29849
|
await this.pnpmReady();
|
|
29354
29850
|
await this.users.ensure();
|
|
29851
|
+
await this.resolvConf();
|
|
29355
29852
|
if (this.owners) await this.stampLayout();
|
|
29356
29853
|
if (this.owners) await this.sudoer.provision();
|
|
29357
29854
|
await writeCaFile(this.base, this.ca).catch(() => void 0);
|
|
@@ -29590,12 +30087,12 @@ var Launcher = class {
|
|
|
29590
30087
|
const out = [];
|
|
29591
30088
|
const err = [];
|
|
29592
30089
|
const keep2 = options.collect !== false;
|
|
29593
|
-
const
|
|
30090
|
+
const collect2 = (chunks2, tee) => (bytes) => {
|
|
29594
30091
|
if (keep2) chunks2.push(bytes);
|
|
29595
30092
|
tee?.(bytes);
|
|
29596
30093
|
};
|
|
29597
|
-
const stdout =
|
|
29598
|
-
const stderr =
|
|
30094
|
+
const stdout = collect2(out, options.onStdout);
|
|
30095
|
+
const stderr = collect2(err, options.onStderr);
|
|
29599
30096
|
const report = (message3) => stderr(encoder10.encode(`${message3}
|
|
29600
30097
|
`));
|
|
29601
30098
|
if (!planned) {
|
|
@@ -30457,7 +30954,7 @@ function parseHead2(bytes) {
|
|
|
30457
30954
|
}
|
|
30458
30955
|
return { status: Number(match[1]), statusText: match[2] ?? "", headers };
|
|
30459
30956
|
}
|
|
30460
|
-
function
|
|
30957
|
+
function header4(head, name2) {
|
|
30461
30958
|
return head.headers.find(([key]) => key.toLowerCase() === name2)?.[1];
|
|
30462
30959
|
}
|
|
30463
30960
|
async function* chunked2(source) {
|
|
@@ -30486,8 +30983,8 @@ async function* untilClose2(source) {
|
|
|
30486
30983
|
}
|
|
30487
30984
|
function bodyOf2(source, head, method) {
|
|
30488
30985
|
if (method === "HEAD" || head.status === 204 || head.status === 304) return void 0;
|
|
30489
|
-
if (
|
|
30490
|
-
const length2 =
|
|
30986
|
+
if (header4(head, "transfer-encoding")?.toLowerCase().includes("chunked")) return chunked2(source);
|
|
30987
|
+
const length2 = header4(head, "content-length");
|
|
30491
30988
|
if (length2 === void 0) return untilClose2(source);
|
|
30492
30989
|
const size = Number(length2);
|
|
30493
30990
|
if (!/^\d+$/.test(length2.trim()) || !Number.isSafeInteger(size)) {
|
|
@@ -31107,6 +31604,7 @@ async function createNodeKernel(options = {}) {
|
|
|
31107
31604
|
...options.env ? { env: options.env } : {},
|
|
31108
31605
|
...transport ? { transport } : {},
|
|
31109
31606
|
...options.network?.uplink ? { uplink: options.network.uplink } : {},
|
|
31607
|
+
...options.network?.doh !== void 0 ? { doh: options.network.doh } : {},
|
|
31110
31608
|
...options.processMounts !== void 0 ? { processMounts: options.processMounts } : {},
|
|
31111
31609
|
...options.fstabRetries ? { fstabRetries: options.fstabRetries } : {},
|
|
31112
31610
|
...options.hostfs ? { hostfs: options.hostfs } : {},
|