@ai-ecoverse/slicc-kernel 1.136.8 → 1.137.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 +22 -4
- package/dist/index.js +3 -1
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +666 -164
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +58 -5
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +653 -160
- 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/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/sealed-pg.d.ts +1 -0
- 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 +3 -3
package/dist/kernel-worker.js
CHANGED
|
@@ -2427,8 +2427,8 @@ var OpfsFs = class {
|
|
|
2427
2427
|
renamingDirs = /* @__PURE__ */ new Set();
|
|
2428
2428
|
intents = 0;
|
|
2429
2429
|
async intend(rename, at = `${RENAMES}/${crypto.randomUUID()}`) {
|
|
2430
|
-
const
|
|
2431
|
-
await this.meta.update(at, () => ({ path: at, rename:
|
|
2430
|
+
const record2 = { ...rename, at: Date.now() * 1e3 + this.intents++ % 1e3 };
|
|
2431
|
+
await this.meta.update(at, () => ({ path: at, rename: record2 }));
|
|
2432
2432
|
return at;
|
|
2433
2433
|
}
|
|
2434
2434
|
async rollBack(from, to, intents) {
|
|
@@ -2939,7 +2939,7 @@ async function rootId(factory, root, locks = globalThis.navigator?.locks) {
|
|
|
2939
2939
|
const all = await request(
|
|
2940
2940
|
db.transaction(ROOTS_STORE, "readonly").objectStore(ROOTS_STORE).getAll()
|
|
2941
2941
|
);
|
|
2942
|
-
for (const
|
|
2942
|
+
for (const record2 of all) if (await same(record2.handle, root)) return record2.id;
|
|
2943
2943
|
const id2 = crypto.randomUUID();
|
|
2944
2944
|
if (await used(root)) await seed(factory, nameOf(id2));
|
|
2945
2945
|
const tx = db.transaction(ROOTS_STORE, "readwrite");
|
|
@@ -4879,6 +4879,15 @@ function isHostname(name2) {
|
|
|
4879
4879
|
function ownNames(hostname) {
|
|
4880
4880
|
return [.../* @__PURE__ */ new Set([hostname.toLowerCase(), ...LIBC_HOSTNAMES])];
|
|
4881
4881
|
}
|
|
4882
|
+
function hostsFile(hostname = DEFAULT_HOSTNAME) {
|
|
4883
|
+
return [
|
|
4884
|
+
"127.0.0.1 localhost localhost.localdomain",
|
|
4885
|
+
"::1 localhost ip6-localhost",
|
|
4886
|
+
`${HOSTNAME_ADDRESS} ${ownNames(hostname).join(" ")}`,
|
|
4887
|
+
`${HOST_LOOPBACK_ADDRESS.join(".")} ${HOST_LOOPBACK}`,
|
|
4888
|
+
""
|
|
4889
|
+
].join("\n");
|
|
4890
|
+
}
|
|
4882
4891
|
|
|
4883
4892
|
// src/kernel/net/routes.ts
|
|
4884
4893
|
var HOST_ADDRESS = HOST_LOOPBACK_ADDRESS.join(".");
|
|
@@ -5563,6 +5572,7 @@ var LOCAL_ONLY = new Routes();
|
|
|
5563
5572
|
var LoopbackNet = class {
|
|
5564
5573
|
bound = /* @__PURE__ */ new Map();
|
|
5565
5574
|
dgrams = /* @__PURE__ */ new Map();
|
|
5575
|
+
dgramServices = /* @__PURE__ */ new Map();
|
|
5566
5576
|
unixDgrams = /* @__PURE__ */ new Map();
|
|
5567
5577
|
activators = /* @__PURE__ */ new Map();
|
|
5568
5578
|
internal = /* @__PURE__ */ new Set();
|
|
@@ -5613,9 +5623,16 @@ var LoopbackNet = class {
|
|
|
5613
5623
|
releaseDgram(addr, socket) {
|
|
5614
5624
|
if (this.dgrams.get(addr.port) === socket) this.dgrams.delete(addr.port);
|
|
5615
5625
|
}
|
|
5616
|
-
|
|
5626
|
+
serveDgram(port, serve) {
|
|
5627
|
+
this.dgramServices.set(port, serve);
|
|
5628
|
+
}
|
|
5629
|
+
deliverDgram(port, datagram2, to) {
|
|
5617
5630
|
const target = this.dgrams.get(port);
|
|
5618
|
-
|
|
5631
|
+
if (target) return target.deliver(datagram2);
|
|
5632
|
+
const service = this.dgramServices.get(port);
|
|
5633
|
+
if (!service) return false;
|
|
5634
|
+
service(datagram2, to ?? { family: "inet", host: "127.0.0.1", port });
|
|
5635
|
+
return true;
|
|
5619
5636
|
}
|
|
5620
5637
|
bindable(addr, kernel) {
|
|
5621
5638
|
if (addr.host !== "0.0.0.0" && !isLoopback(addr.host)) {
|
|
@@ -7098,7 +7115,7 @@ function satisfies(version, range2) {
|
|
|
7098
7115
|
}
|
|
7099
7116
|
|
|
7100
7117
|
// src/version.ts
|
|
7101
|
-
var KERNEL_VERSION = true ? "1.
|
|
7118
|
+
var KERNEL_VERSION = true ? "1.137.0" : "0.0.0-dev";
|
|
7102
7119
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7103
7120
|
function procVersion() {
|
|
7104
7121
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -8616,11 +8633,11 @@ var CronService = class {
|
|
|
8616
8633
|
}
|
|
8617
8634
|
if (this.stopping.signal.aborted) return;
|
|
8618
8635
|
const exit = ended.signal ? `signal=${ended.signal}` : `exit=${ended.status}`;
|
|
8619
|
-
const
|
|
8636
|
+
const header4 = encoder.encode(`--- ${iso} ${exit} missed=${missed} ---
|
|
8620
8637
|
`);
|
|
8621
8638
|
const body = output.bytes();
|
|
8622
8639
|
const newline = body.length > 0 && body[body.length - 1] !== 10 ? encoder.encode("\n") : new Uint8Array();
|
|
8623
|
-
await this.append(log, concat2([
|
|
8640
|
+
await this.append(log, concat2([header4, body, newline]), account.uid, account.gid).catch(
|
|
8624
8641
|
(err) => this.error(messageOf(err))
|
|
8625
8642
|
);
|
|
8626
8643
|
}
|
|
@@ -9428,8 +9445,8 @@ var FileWatches = class {
|
|
|
9428
9445
|
live = /* @__PURE__ */ new Set();
|
|
9429
9446
|
local;
|
|
9430
9447
|
remote;
|
|
9431
|
-
constructor(
|
|
9432
|
-
this.local =
|
|
9448
|
+
constructor(local2, remote) {
|
|
9449
|
+
this.local = local2;
|
|
9433
9450
|
this.remote = remote;
|
|
9434
9451
|
}
|
|
9435
9452
|
announce() {
|
|
@@ -13149,18 +13166,18 @@ var SAB_I_ASYNC = 14;
|
|
|
13149
13166
|
var SAB_I_STOP = 15;
|
|
13150
13167
|
var SAB_I_BLOCKED = 16;
|
|
13151
13168
|
var SAB_I_BLOCKED_HI = 17;
|
|
13152
|
-
function loadBlocked(
|
|
13153
|
-
return [Atomics.load(
|
|
13169
|
+
function loadBlocked(header4) {
|
|
13170
|
+
return [Atomics.load(header4, SAB_I_BLOCKED), Atomics.load(header4, SAB_I_BLOCKED_HI)];
|
|
13154
13171
|
}
|
|
13155
|
-
function storeBlocked(
|
|
13156
|
-
Atomics.store(
|
|
13157
|
-
Atomics.store(
|
|
13172
|
+
function storeBlocked(header4, [low, high]) {
|
|
13173
|
+
Atomics.store(header4, SAB_I_BLOCKED_HI, high);
|
|
13174
|
+
Atomics.store(header4, SAB_I_BLOCKED, low);
|
|
13158
13175
|
}
|
|
13159
13176
|
var anyBlocked = (mask) => mask !== void 0 && (mask[0] !== 0 || mask[1] !== 0);
|
|
13160
13177
|
var U32 = 2 ** 32;
|
|
13161
|
-
function storeU53(
|
|
13162
|
-
Atomics.store(
|
|
13163
|
-
Atomics.store(
|
|
13178
|
+
function storeU53(header4, lo, hi, value2) {
|
|
13179
|
+
Atomics.store(header4, hi, Math.floor(value2 / U32));
|
|
13180
|
+
Atomics.store(header4, lo, value2 % U32 | 0);
|
|
13164
13181
|
}
|
|
13165
13182
|
var SAB_STATE_READY = 2;
|
|
13166
13183
|
var SAB_STATUS_BYTES = 1;
|
|
@@ -13209,7 +13226,7 @@ function sabViews(sab) {
|
|
|
13209
13226
|
var PENDING_TTL_MS = SYNC_FS_REQUEST_TIMEOUT_MS + 5e3;
|
|
13210
13227
|
function attachSyncSabResponder(port, sab, token, opts) {
|
|
13211
13228
|
const views = sabViews(sab);
|
|
13212
|
-
const { header:
|
|
13229
|
+
const { header: header4, window } = views;
|
|
13213
13230
|
const pending = /* @__PURE__ */ new Map();
|
|
13214
13231
|
let disposed = false;
|
|
13215
13232
|
const { dispatch: dispatch2 } = opts;
|
|
@@ -13220,20 +13237,20 @@ function attachSyncSabResponder(port, sab, token, opts) {
|
|
|
13220
13237
|
pending.delete(id2);
|
|
13221
13238
|
}
|
|
13222
13239
|
function publish(id2, entry, offset) {
|
|
13223
|
-
if (Atomics.load(
|
|
13240
|
+
if (Atomics.load(header4, SAB_I_REQ) !== id2) {
|
|
13224
13241
|
drop(id2);
|
|
13225
13242
|
return;
|
|
13226
13243
|
}
|
|
13227
13244
|
const chunk2 = Math.min(window.byteLength, entry.payload.byteLength - offset);
|
|
13228
13245
|
if (chunk2 > 0) window.set(entry.payload.subarray(offset, offset + chunk2));
|
|
13229
|
-
Atomics.store(
|
|
13230
|
-
storeU53(
|
|
13231
|
-
Atomics.store(
|
|
13232
|
-
storeU53(
|
|
13233
|
-
Atomics.store(
|
|
13234
|
-
Atomics.store(
|
|
13235
|
-
Atomics.add(
|
|
13236
|
-
Atomics.notify(
|
|
13246
|
+
Atomics.store(header4, SAB_I_STATUS, entry.status);
|
|
13247
|
+
storeU53(header4, SAB_I_TOTAL, SAB_I_TOTAL_HI, entry.payload.byteLength);
|
|
13248
|
+
Atomics.store(header4, SAB_I_CHUNK, chunk2);
|
|
13249
|
+
storeU53(header4, SAB_I_OFFSET, SAB_I_OFFSET_HI, offset);
|
|
13250
|
+
Atomics.store(header4, SAB_I_SEQ, id2);
|
|
13251
|
+
Atomics.store(header4, SAB_I_STATE, SAB_STATE_READY);
|
|
13252
|
+
Atomics.add(header4, SAB_I_PUB, 1);
|
|
13253
|
+
Atomics.notify(header4, SAB_I_PUB);
|
|
13237
13254
|
if (offset + chunk2 >= entry.payload.byteLength) drop(id2);
|
|
13238
13255
|
else if (entry.timer) {
|
|
13239
13256
|
clearTimeout(entry.timer);
|
|
@@ -13448,6 +13465,15 @@ var ProcessClocks = class {
|
|
|
13448
13465
|
}
|
|
13449
13466
|
};
|
|
13450
13467
|
|
|
13468
|
+
// src/kernel/proc-info.ts
|
|
13469
|
+
function mayTrace(viewer, target) {
|
|
13470
|
+
const by = viewer?.cred;
|
|
13471
|
+
const of = target.cred;
|
|
13472
|
+
if (!by || !of || by.euid === 0) return true;
|
|
13473
|
+
const uid = of.ruid === by.euid && of.euid === by.euid && of.suid === by.euid;
|
|
13474
|
+
return uid && of.rgid === by.egid && of.egid === by.egid && of.sgid === by.egid;
|
|
13475
|
+
}
|
|
13476
|
+
|
|
13451
13477
|
// src/fs/pages.ts
|
|
13452
13478
|
var PAGE = 64 * 1024;
|
|
13453
13479
|
var READAHEAD = 1024 * 1024;
|
|
@@ -14003,7 +14029,16 @@ var ProcTree = class {
|
|
|
14003
14029
|
if (!/^[1-9]\d*$/.test(top) || !this.alive(Number(top))) return void 0;
|
|
14004
14030
|
if (leaf === "task") return this.task(Number(top), rest2);
|
|
14005
14031
|
if (rest2.length > 0) return void 0;
|
|
14006
|
-
if (leaf === void 0)
|
|
14032
|
+
if (leaf === void 0) {
|
|
14033
|
+
const exe = () => this.info(Number(top))?.exe === void 0 ? [] : ["exe"];
|
|
14034
|
+
return { kind: "dir", names: () => [...PID_NAMES, ...exe(), "task"] };
|
|
14035
|
+
}
|
|
14036
|
+
if (leaf === "exe") {
|
|
14037
|
+
const info = this.info(Number(top));
|
|
14038
|
+
if (info?.exe === void 0) return void 0;
|
|
14039
|
+
const denied2 = !mayTrace(this.ownInfo(), info);
|
|
14040
|
+
return { kind: "link", target: info.exe, ...denied2 ? { denied: denied2 } : {} };
|
|
14041
|
+
}
|
|
14007
14042
|
if (!PID_NAMES.includes(leaf)) return void 0;
|
|
14008
14043
|
return {
|
|
14009
14044
|
kind: "file",
|
|
@@ -14015,6 +14050,10 @@ var ProcTree = class {
|
|
|
14015
14050
|
}
|
|
14016
14051
|
};
|
|
14017
14052
|
}
|
|
14053
|
+
ownInfo() {
|
|
14054
|
+
const processes2 = this.listing().processes;
|
|
14055
|
+
return processes2.find((p) => p.tid === this.pid) ?? processes2.find((p) => p.pid === this.pid);
|
|
14056
|
+
}
|
|
14018
14057
|
info(pid) {
|
|
14019
14058
|
return this.listing().processes.find((p) => p.pid === pid);
|
|
14020
14059
|
}
|
|
@@ -14078,6 +14117,7 @@ var ProcTree = class {
|
|
|
14078
14117
|
readlink(path) {
|
|
14079
14118
|
const node = this.find(path, false);
|
|
14080
14119
|
if (node.kind !== "link") throw syncError("EINVAL", path);
|
|
14120
|
+
if (node.denied) throw syncError("EACCES", path);
|
|
14081
14121
|
return node.target;
|
|
14082
14122
|
}
|
|
14083
14123
|
exists(path) {
|
|
@@ -15482,8 +15522,8 @@ function sameCert(a, b) {
|
|
|
15482
15522
|
if (!a || !b) return a === b;
|
|
15483
15523
|
return a.cert.length === b.cert.length && a.cert.every((byte, i) => byte === b.cert[i]);
|
|
15484
15524
|
}
|
|
15485
|
-
function winner(current, expected,
|
|
15486
|
-
return sameCert(current, expected) ?
|
|
15525
|
+
function winner(current, expected, record2) {
|
|
15526
|
+
return sameCert(current, expected) ? record2 : current;
|
|
15487
15527
|
}
|
|
15488
15528
|
var DAY = 24 * 60 * 60 * 1e3;
|
|
15489
15529
|
var CA_LIFETIME = 3650 * DAY;
|
|
@@ -15516,15 +15556,15 @@ function indexedDbCaStore(dbName = "slicc-realm-ca") {
|
|
|
15516
15556
|
const store = (await open2()).transaction("ca").objectStore("ca");
|
|
15517
15557
|
return await request2(store.get(owner));
|
|
15518
15558
|
},
|
|
15519
|
-
async swap(owner, expected,
|
|
15559
|
+
async swap(owner, expected, record2) {
|
|
15520
15560
|
const tx = (await open2()).transaction("ca", "readwrite");
|
|
15521
15561
|
const store = tx.objectStore("ca");
|
|
15522
|
-
let stored =
|
|
15562
|
+
let stored = record2;
|
|
15523
15563
|
const read = store.get(owner);
|
|
15524
15564
|
read.onsuccess = () => {
|
|
15525
15565
|
const current = read.result;
|
|
15526
|
-
const kept = winner(current, expected,
|
|
15527
|
-
if (kept ===
|
|
15566
|
+
const kept = winner(current, expected, record2);
|
|
15567
|
+
if (kept === record2) store.put(record2, owner);
|
|
15528
15568
|
else stored = kept;
|
|
15529
15569
|
};
|
|
15530
15570
|
await new Promise((resolve2, reject) => {
|
|
@@ -15544,14 +15584,14 @@ function validLeafName(host) {
|
|
|
15544
15584
|
}
|
|
15545
15585
|
var RealmCa = class _RealmCa {
|
|
15546
15586
|
record;
|
|
15547
|
-
constructor(
|
|
15548
|
-
this.record =
|
|
15587
|
+
constructor(record2) {
|
|
15588
|
+
this.record = record2;
|
|
15549
15589
|
}
|
|
15550
15590
|
static async open(owner, store, now = Date.now()) {
|
|
15551
15591
|
const stored = await store.get(owner).catch(() => void 0);
|
|
15552
15592
|
if (stored && stored.notAfter - now > CA_RENEW_BEFORE) return new _RealmCa(stored);
|
|
15553
|
-
const
|
|
15554
|
-
return new _RealmCa(await store.swap(owner, stored,
|
|
15593
|
+
const record2 = await _RealmCa.create(owner, now);
|
|
15594
|
+
return new _RealmCa(await store.swap(owner, stored, record2));
|
|
15555
15595
|
}
|
|
15556
15596
|
static async create(owner, now) {
|
|
15557
15597
|
const pair = await crypto.subtle.generateKey(ECDSA, false, ["sign", "verify"]);
|
|
@@ -16082,8 +16122,8 @@ function memoryCaStore() {
|
|
|
16082
16122
|
const records = /* @__PURE__ */ new Map();
|
|
16083
16123
|
return {
|
|
16084
16124
|
get: async (owner) => records.get(owner),
|
|
16085
|
-
swap: async (owner, expected,
|
|
16086
|
-
const kept = winner(records.get(owner), expected,
|
|
16125
|
+
swap: async (owner, expected, record2) => {
|
|
16126
|
+
const kept = winner(records.get(owner), expected, record2);
|
|
16087
16127
|
records.set(owner, kept);
|
|
16088
16128
|
return kept;
|
|
16089
16129
|
}
|
|
@@ -16213,10 +16253,10 @@ var WsHandles = class {
|
|
|
16213
16253
|
open = /* @__PURE__ */ new Map();
|
|
16214
16254
|
next;
|
|
16215
16255
|
local;
|
|
16216
|
-
constructor(transport, next3,
|
|
16256
|
+
constructor(transport, next3, local2) {
|
|
16217
16257
|
this.transport = transport;
|
|
16218
16258
|
this.next = next3;
|
|
16219
|
-
this.local =
|
|
16259
|
+
this.local = local2;
|
|
16220
16260
|
}
|
|
16221
16261
|
owns(handle) {
|
|
16222
16262
|
return this.open.has(handle);
|
|
@@ -16245,8 +16285,8 @@ var WsHandles = class {
|
|
|
16245
16285
|
return { ok: true, kind: "json", json: handle };
|
|
16246
16286
|
}
|
|
16247
16287
|
async connect(handle, req, entry) {
|
|
16248
|
-
const { transport, local } = this;
|
|
16249
|
-
const port =
|
|
16288
|
+
const { transport, local: local2 } = this;
|
|
16289
|
+
const port = local2?.port(req.url);
|
|
16250
16290
|
const open2 = { protocols: req.protocols, headers: req.headers, signal: entry.abort.signal };
|
|
16251
16291
|
if (port === void 0 && (!transport.traits.websocket || !transport.websocket)) {
|
|
16252
16292
|
return fail("ENOTSUP", NO_WEBSOCKET2);
|
|
@@ -16256,7 +16296,7 @@ var WsHandles = class {
|
|
|
16256
16296
|
socket = port === void 0 ? await transport.websocket({
|
|
16257
16297
|
url: toHostLoopback(req.url),
|
|
16258
16298
|
...open2
|
|
16259
|
-
}) : await
|
|
16299
|
+
}) : await local2.websocket({ url: req.url, ...open2 }, port);
|
|
16260
16300
|
} catch (e) {
|
|
16261
16301
|
return fail(errnoOf(e), message(e));
|
|
16262
16302
|
}
|
|
@@ -16387,11 +16427,11 @@ var HttpHandles = class {
|
|
|
16387
16427
|
ws;
|
|
16388
16428
|
owner;
|
|
16389
16429
|
local;
|
|
16390
|
-
constructor(transport, owner,
|
|
16430
|
+
constructor(transport, owner, local2) {
|
|
16391
16431
|
this.transport = transport;
|
|
16392
16432
|
this.owner = owner;
|
|
16393
|
-
this.local =
|
|
16394
|
-
this.ws = new WsHandles(transport, () => ++this.nextHandle,
|
|
16433
|
+
this.local = local2;
|
|
16434
|
+
this.ws = new WsHandles(transport, () => ++this.nextHandle, local2);
|
|
16395
16435
|
}
|
|
16396
16436
|
syscall(req) {
|
|
16397
16437
|
if (req.op.startsWith("net-ws-")) return this.ws.syscall(req);
|
|
@@ -16543,6 +16583,43 @@ var HttpHandles = class {
|
|
|
16543
16583
|
}
|
|
16544
16584
|
};
|
|
16545
16585
|
|
|
16586
|
+
// src/kernel/net/hosts-file.ts
|
|
16587
|
+
var HOSTS_PATH = "/etc/hosts";
|
|
16588
|
+
function parseHosts(text) {
|
|
16589
|
+
const table = /* @__PURE__ */ new Map();
|
|
16590
|
+
for (const raw2 of text.split("\n")) {
|
|
16591
|
+
const [address, ...names2] = raw2.replace(/#.*/, "").trim().split(/\s+/);
|
|
16592
|
+
if (!address || names2.length === 0) continue;
|
|
16593
|
+
if (ipv4Bytes(address) === void 0 && ipv6Groups(address) === void 0) continue;
|
|
16594
|
+
for (const name2 of names2) {
|
|
16595
|
+
const key = name2.toLowerCase().replace(/\.$/, "");
|
|
16596
|
+
const known = table.get(key) ?? [];
|
|
16597
|
+
if (!known.includes(address)) known.push(address);
|
|
16598
|
+
table.set(key, known);
|
|
16599
|
+
}
|
|
16600
|
+
}
|
|
16601
|
+
return table;
|
|
16602
|
+
}
|
|
16603
|
+
function hostsReader(fs, path = HOSTS_PATH) {
|
|
16604
|
+
let stamp = "";
|
|
16605
|
+
let table;
|
|
16606
|
+
return async () => {
|
|
16607
|
+
const st = await fs.stat(path).catch(() => void 0);
|
|
16608
|
+
if (!st?.isFile) {
|
|
16609
|
+
stamp = "";
|
|
16610
|
+
table = void 0;
|
|
16611
|
+
return void 0;
|
|
16612
|
+
}
|
|
16613
|
+
const now = `${st.ino}:${st.size}:${st.mtime.getTime()}`;
|
|
16614
|
+
if (now === stamp && table) return table;
|
|
16615
|
+
const text = await fs.readFile(path).catch(() => void 0);
|
|
16616
|
+
if (text === void 0) return void 0;
|
|
16617
|
+
stamp = now;
|
|
16618
|
+
table = parseHosts(text);
|
|
16619
|
+
return table;
|
|
16620
|
+
};
|
|
16621
|
+
}
|
|
16622
|
+
|
|
16546
16623
|
// src/kernel/net/uplink.ts
|
|
16547
16624
|
function carriesUdp(uplink) {
|
|
16548
16625
|
return uplink.traits.udp === true && typeof uplink.udp === "function";
|
|
@@ -16559,13 +16636,15 @@ var NEVER = new Routes(true);
|
|
|
16559
16636
|
var RemoteUplink = class {
|
|
16560
16637
|
traits;
|
|
16561
16638
|
routes;
|
|
16639
|
+
nameserver;
|
|
16562
16640
|
port;
|
|
16563
16641
|
waiting = /* @__PURE__ */ new Map();
|
|
16564
16642
|
nextId = 0;
|
|
16565
|
-
constructor(port, traits, routes) {
|
|
16643
|
+
constructor(port, traits, routes, nameserver) {
|
|
16566
16644
|
this.port = port;
|
|
16567
16645
|
this.traits = traits;
|
|
16568
16646
|
this.routes = routes;
|
|
16647
|
+
this.nameserver = nameserver;
|
|
16569
16648
|
}
|
|
16570
16649
|
receive(reply) {
|
|
16571
16650
|
const waiter = this.waiting.get(reply.uid);
|
|
@@ -16688,6 +16767,7 @@ var Resolver = class {
|
|
|
16688
16767
|
timeoutMs;
|
|
16689
16768
|
log;
|
|
16690
16769
|
own;
|
|
16770
|
+
builtin;
|
|
16691
16771
|
cache = /* @__PURE__ */ new Map();
|
|
16692
16772
|
pending = /* @__PURE__ */ new Map();
|
|
16693
16773
|
hosts;
|
|
@@ -16698,6 +16778,7 @@ var Resolver = class {
|
|
|
16698
16778
|
this.timeoutMs = options.timeoutMs ?? RESOLVE_TIMEOUT_MS;
|
|
16699
16779
|
this.log = options.log ?? ((message3) => console.warn(message3));
|
|
16700
16780
|
this.own = ownNames(options.hostname ?? DEFAULT_HOSTNAME);
|
|
16781
|
+
this.builtin = parseHosts(hostsFile(options.hostname ?? DEFAULT_HOSTNAME));
|
|
16701
16782
|
this.hosts = options.hosts;
|
|
16702
16783
|
}
|
|
16703
16784
|
async fromFile(key, family) {
|
|
@@ -16707,18 +16788,34 @@ var Resolver = class {
|
|
|
16707
16788
|
const v6 = listed.filter((a) => ipv4Bytes(a) === void 0);
|
|
16708
16789
|
return family === 4 ? v4 : family === 6 ? v6 : [...v4, ...v6];
|
|
16709
16790
|
}
|
|
16791
|
+
async known(name2) {
|
|
16792
|
+
const key = name2.toLowerCase().replace(/\.$/, "");
|
|
16793
|
+
if (ipv4Bytes(key) || ipv6Groups(key)) return false;
|
|
16794
|
+
if (hostsEntry(key, this.own) !== void 0) return true;
|
|
16795
|
+
return ((await this.hosts?.().catch(() => void 0))?.get(key)?.length ?? 0) > 0;
|
|
16796
|
+
}
|
|
16797
|
+
async reverse(address) {
|
|
16798
|
+
const v6 = ipv6Groups(address)?.join(":");
|
|
16799
|
+
const same3 = (a) => a === address || v6 !== void 0 && ipv6Groups(a)?.join(":") === v6;
|
|
16800
|
+
const file = await this.hosts?.().catch(() => void 0);
|
|
16801
|
+
for (const table of [file, this.builtin]) {
|
|
16802
|
+
for (const [name2, addresses] of table ?? []) if (addresses.some(same3)) return name2;
|
|
16803
|
+
}
|
|
16804
|
+
if (ipv4Bytes(address)?.[0] === 127) return "localhost";
|
|
16805
|
+
return void 0;
|
|
16806
|
+
}
|
|
16710
16807
|
async resolve(name2, family, blocking) {
|
|
16711
16808
|
const key = name2.toLowerCase().replace(/\.$/, "");
|
|
16712
|
-
const
|
|
16809
|
+
const local2 = hostsEntry(key, this.own);
|
|
16713
16810
|
if (ipv6Groups(key)) {
|
|
16714
|
-
const v4 = family !== 6 &&
|
|
16811
|
+
const v4 = family !== 6 && local2 ? [local2] : [];
|
|
16715
16812
|
return family === 4 ? v4 : [...v4, key];
|
|
16716
16813
|
}
|
|
16717
16814
|
const listed = this.hosts ? await this.fromFile(key, family) : void 0;
|
|
16718
16815
|
if (listed?.length) return listed;
|
|
16719
|
-
if (
|
|
16816
|
+
if (local2) {
|
|
16720
16817
|
const six = loopbackName(key, this.own) ? ["::1"] : [];
|
|
16721
|
-
return family === 6 ? six : family === 4 ? [
|
|
16818
|
+
return family === 6 ? six : family === 4 ? [local2] : [local2, ...six];
|
|
16722
16819
|
}
|
|
16723
16820
|
if (!this.uplink || key === "") return [];
|
|
16724
16821
|
const asked = this.uplink.traits.ipv6 ? family : 4;
|
|
@@ -17757,14 +17854,15 @@ var KernelDgram = class {
|
|
|
17757
17854
|
const max = familyOf(target.host) === 6 ? MAX_DATAGRAM_V6 : MAX_DATAGRAM_V4;
|
|
17758
17855
|
if (bytes.length > max) throw new KernelError("EMSGSIZE");
|
|
17759
17856
|
const where = this.route(target.host);
|
|
17760
|
-
const
|
|
17857
|
+
const local2 = this.bound();
|
|
17761
17858
|
if (where === "uplink") return this.sendUp(bytes, target);
|
|
17762
17859
|
const from = {
|
|
17763
17860
|
family: "inet",
|
|
17764
|
-
host:
|
|
17765
|
-
port:
|
|
17861
|
+
host: local2.host === "0.0.0.0" ? "127.0.0.1" : local2.host,
|
|
17862
|
+
port: local2.port
|
|
17766
17863
|
};
|
|
17767
|
-
const
|
|
17864
|
+
const dest = { family: "inet", host: canonicalHost(target.host), port: target.port };
|
|
17865
|
+
const delivered = this.net.deliverDgram(target.port, { bytes: bytes.slice(), from }, dest);
|
|
17768
17866
|
if (!delivered && this.peer && sameAddr(this.peer, target)) {
|
|
17769
17867
|
this.pending = "ECONNREFUSED";
|
|
17770
17868
|
this.changes.wake();
|
|
@@ -19361,8 +19459,8 @@ function clientFirstOf(message3) {
|
|
|
19361
19459
|
return m ? { header: m[1], bare: m[2] } : void 0;
|
|
19362
19460
|
}
|
|
19363
19461
|
var latinBytes = (text) => Uint8Array.from(text, (c) => c.charCodeAt(0));
|
|
19364
|
-
function channelOf(
|
|
19365
|
-
const head = latinBytes(
|
|
19462
|
+
function channelOf(header4, binding) {
|
|
19463
|
+
const head = latinBytes(header4);
|
|
19366
19464
|
const all = new Uint8Array(head.length + (binding?.length ?? 0));
|
|
19367
19465
|
all.set(head);
|
|
19368
19466
|
if (binding) all.set(binding, head.length);
|
|
@@ -19484,6 +19582,7 @@ function latin2(bytes) {
|
|
|
19484
19582
|
var PgServer = class {
|
|
19485
19583
|
binding;
|
|
19486
19584
|
plus = false;
|
|
19585
|
+
touch;
|
|
19487
19586
|
constructor(binding) {
|
|
19488
19587
|
this.binding = binding;
|
|
19489
19588
|
}
|
|
@@ -19505,6 +19604,7 @@ var PgServer = class {
|
|
|
19505
19604
|
return message3;
|
|
19506
19605
|
}
|
|
19507
19606
|
mechanisms(message3) {
|
|
19607
|
+
if (this.touch !== true) return message3;
|
|
19508
19608
|
this.sasl = true;
|
|
19509
19609
|
const offered = latin2(message3.subarray(9)).split("\0").filter((n) => n !== "");
|
|
19510
19610
|
this.plus = offered.includes(PLUS);
|
|
@@ -19585,8 +19685,8 @@ function frame3(type, body) {
|
|
|
19585
19685
|
return out;
|
|
19586
19686
|
}
|
|
19587
19687
|
function pgLength(bytes, started) {
|
|
19588
|
-
const
|
|
19589
|
-
if (bytes.length <
|
|
19688
|
+
const header4 = started ? 5 : 4;
|
|
19689
|
+
if (bytes.length < header4) return void 0;
|
|
19590
19690
|
const length2 = int32(bytes, started ? 1 : 0);
|
|
19591
19691
|
return started ? 1 + length2 : length2;
|
|
19592
19692
|
}
|
|
@@ -19614,16 +19714,16 @@ function initial(message3) {
|
|
|
19614
19714
|
function int32Text(n) {
|
|
19615
19715
|
return String.fromCharCode(n >>> 24 & 255, n >>> 16 & 255, n >>> 8 & 255, n & 255);
|
|
19616
19716
|
}
|
|
19617
|
-
function serverHeader(
|
|
19618
|
-
if (
|
|
19619
|
-
if (
|
|
19620
|
-
if (
|
|
19717
|
+
function serverHeader(header4, server) {
|
|
19718
|
+
if (header4 === "n,,") return header4;
|
|
19719
|
+
if (header4 === "y,," && !server.plus) return header4;
|
|
19720
|
+
if (header4 === END_POINT && server.binding) return header4;
|
|
19621
19721
|
return server.plus && server.binding ? END_POINT : "n,,";
|
|
19622
19722
|
}
|
|
19623
|
-
function rewritten(first,
|
|
19723
|
+
function rewritten(first, header4) {
|
|
19624
19724
|
const parsed2 = clientFirstOf(first.data);
|
|
19625
|
-
if (!parsed2 || parsed2.header ===
|
|
19626
|
-
return { mechanism:
|
|
19725
|
+
if (!parsed2 || parsed2.header === header4) return first;
|
|
19726
|
+
return { mechanism: header4 === END_POINT ? PLUS : PLAIN, data: `${header4}${parsed2.bare}` };
|
|
19627
19727
|
}
|
|
19628
19728
|
var PgClient = class {
|
|
19629
19729
|
clientFirst;
|
|
@@ -19864,6 +19964,10 @@ var SessionWriter = class {
|
|
|
19864
19964
|
this.proven ??= this.prove(protocol).catch(() => void 0);
|
|
19865
19965
|
return this.proven;
|
|
19866
19966
|
}
|
|
19967
|
+
async mayTouch() {
|
|
19968
|
+
if (this.s.verified) return true;
|
|
19969
|
+
return (await this.proof("pg"))?.anchor !== void 0;
|
|
19970
|
+
}
|
|
19867
19971
|
async prove(protocol) {
|
|
19868
19972
|
const s = this.s;
|
|
19869
19973
|
if (s.anchoring) {
|
|
@@ -19913,7 +20017,10 @@ var SessionWriter = class {
|
|
|
19913
20017
|
this.buffer.fill(0);
|
|
19914
20018
|
this.buffer = joined4;
|
|
19915
20019
|
if (this.mode === "sniff") this.mode = modeOf(latin12(joined4.subarray(0, 8))) ?? "sniff";
|
|
19916
|
-
if (this.mode === "pg"
|
|
20020
|
+
if (this.mode === "pg" && !this.sawPg) {
|
|
20021
|
+
this.sawPg = true;
|
|
20022
|
+
if (!this.s.verified) void this.proof("pg");
|
|
20023
|
+
}
|
|
19917
20024
|
if (this.mode === "pass") await this.release();
|
|
19918
20025
|
else if (this.mode === "http1") await this.http1();
|
|
19919
20026
|
else if (this.mode === "smtp") await this.lines();
|
|
@@ -20093,6 +20200,7 @@ function sealedConn(conn, s) {
|
|
|
20093
20200
|
for (; ; ) {
|
|
20094
20201
|
const bytes = await conn.read();
|
|
20095
20202
|
if (!bytes) return bytes;
|
|
20203
|
+
if (writer?.sawPg && pg.touch === void 0) pg.touch = await writer.mayTouch();
|
|
20096
20204
|
const out = writer?.sawPg ? pg.filter(bytes) : bytes;
|
|
20097
20205
|
if (pg.failed) {
|
|
20098
20206
|
conn.close();
|
|
@@ -20740,8 +20848,8 @@ async function datagram(req, proc) {
|
|
|
20740
20848
|
const ready2 = pollFile(dgram).readable;
|
|
20741
20849
|
if (req.nonblock && !ready2) throw new KernelError("EAGAIN");
|
|
20742
20850
|
const got = await dgram.receive(req.max, req.peek, ready2 ? void 0 : proc.blocking());
|
|
20743
|
-
const { bytes, from, truncated } = got;
|
|
20744
|
-
return { ok: true, kind: "bytes", bytes: encodeReceived({ bytes, truncated, ...from }) };
|
|
20851
|
+
const { bytes, from, truncated: truncated2 } = got;
|
|
20852
|
+
return { ok: true, kind: "bytes", bytes: encodeReceived({ bytes, truncated: truncated2, ...from }) };
|
|
20745
20853
|
}
|
|
20746
20854
|
async function unixDatagram(req, dgram, proc) {
|
|
20747
20855
|
if (req.op === "sock-sendto") {
|
|
@@ -20751,11 +20859,11 @@ async function unixDatagram(req, dgram, proc) {
|
|
|
20751
20859
|
const ready2 = pollFile(dgram).readable;
|
|
20752
20860
|
if (req.nonblock && !ready2) throw new KernelError("EAGAIN");
|
|
20753
20861
|
const got = await dgram.receive(req.max, req.peek, ready2 ? void 0 : proc.blocking());
|
|
20754
|
-
const { bytes, from, truncated } = got;
|
|
20862
|
+
const { bytes, from, truncated: truncated2 } = got;
|
|
20755
20863
|
return {
|
|
20756
20864
|
ok: true,
|
|
20757
20865
|
kind: "bytes",
|
|
20758
|
-
bytes: encodeReceived({ bytes, truncated, host: from.path, port: 0, unix: true })
|
|
20866
|
+
bytes: encodeReceived({ bytes, truncated: truncated2, host: from.path, port: 0, unix: true })
|
|
20759
20867
|
};
|
|
20760
20868
|
}
|
|
20761
20869
|
function domainOf(socket) {
|
|
@@ -23506,9 +23614,9 @@ var JsThreads = class {
|
|
|
23506
23614
|
const { control, port } = msg;
|
|
23507
23615
|
const tid = ++this.last;
|
|
23508
23616
|
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
23509
|
-
const
|
|
23617
|
+
const header4 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
23510
23618
|
const owned4 = new SharedArrayBuffer(4 * (1 + JS_THREAD_OWNED_FDS));
|
|
23511
|
-
if (this.frozen) Atomics.store(
|
|
23619
|
+
if (this.frozen) Atomics.store(header4, SAB_I_STOP, 1);
|
|
23512
23620
|
const clock = this.deps.clocks.thread(tid + 1, sab);
|
|
23513
23621
|
let ended = false;
|
|
23514
23622
|
const end = (code) => {
|
|
@@ -23516,7 +23624,7 @@ var JsThreads = class {
|
|
|
23516
23624
|
ended = true;
|
|
23517
23625
|
this.live.delete(tid);
|
|
23518
23626
|
this.headers.delete(tid);
|
|
23519
|
-
this.deps.wakes.delete(
|
|
23627
|
+
this.deps.wakes.delete(header4);
|
|
23520
23628
|
for (const [id2, token] of ops) {
|
|
23521
23629
|
void this.deps.dispatch({ op: "async-cancel", id: id2, token });
|
|
23522
23630
|
}
|
|
@@ -23566,8 +23674,8 @@ var JsThreads = class {
|
|
|
23566
23674
|
control.addEventListener("message", onControl);
|
|
23567
23675
|
control.start();
|
|
23568
23676
|
this.live.set(tid, end);
|
|
23569
|
-
this.headers.set(tid,
|
|
23570
|
-
this.deps.wakes.add(
|
|
23677
|
+
this.headers.set(tid, header4);
|
|
23678
|
+
this.deps.wakes.add(header4);
|
|
23571
23679
|
const init = {
|
|
23572
23680
|
...this.deps.init(sab, lane.lane),
|
|
23573
23681
|
type: JS_THREAD_INIT,
|
|
@@ -23587,9 +23695,9 @@ var JsThreads = class {
|
|
|
23587
23695
|
}
|
|
23588
23696
|
stopped(stopped) {
|
|
23589
23697
|
this.frozen = stopped;
|
|
23590
|
-
for (const
|
|
23591
|
-
Atomics.store(
|
|
23592
|
-
Atomics.notify(
|
|
23698
|
+
for (const header4 of this.headers.values()) {
|
|
23699
|
+
Atomics.store(header4, SAB_I_STOP, stopped ? 1 : 0);
|
|
23700
|
+
Atomics.notify(header4, SAB_I_STOP);
|
|
23593
23701
|
}
|
|
23594
23702
|
}
|
|
23595
23703
|
close() {
|
|
@@ -23634,13 +23742,13 @@ var Dying = class {
|
|
|
23634
23742
|
hard;
|
|
23635
23743
|
busy = 0;
|
|
23636
23744
|
finish;
|
|
23637
|
-
start(code, sig,
|
|
23745
|
+
start(code, sig, header4, process, finish) {
|
|
23638
23746
|
if (this.ending) return;
|
|
23639
23747
|
this.ending = { code, sig };
|
|
23640
23748
|
this.finish = finish;
|
|
23641
23749
|
this.hard = setTimeout(finish, KILL_HARD_MS);
|
|
23642
23750
|
this.arm();
|
|
23643
|
-
Atomics.store(
|
|
23751
|
+
Atomics.store(header4, SAB_I_KILLED, code);
|
|
23644
23752
|
process.die();
|
|
23645
23753
|
}
|
|
23646
23754
|
serve(req, work) {
|
|
@@ -23687,8 +23795,8 @@ function unblockedThread(threads, sig) {
|
|
|
23687
23795
|
}
|
|
23688
23796
|
return void 0;
|
|
23689
23797
|
}
|
|
23690
|
-
function unblocked(
|
|
23691
|
-
return Atomics.load(
|
|
23798
|
+
function unblocked(header4) {
|
|
23799
|
+
return Atomics.load(header4, SAB_I_SIGNALS) & ~Atomics.load(header4, SAB_I_BLOCKED);
|
|
23692
23800
|
}
|
|
23693
23801
|
function threadCall(process, req, cancelled, block) {
|
|
23694
23802
|
return isWasmSyscall(req) ? process.syscall(req, cancelled, block) : dispatchSyncFs(req);
|
|
@@ -23700,24 +23808,24 @@ function threadCancel(thread) {
|
|
|
23700
23808
|
return unblocked(thread.header) !== 0 ? AbortSignal.abort() : thread.interrupt.signal;
|
|
23701
23809
|
}
|
|
23702
23810
|
var asyncFanout = /* @__PURE__ */ new WeakMap();
|
|
23703
|
-
function notifiers(
|
|
23811
|
+
function notifiers(header4) {
|
|
23704
23812
|
return {
|
|
23705
23813
|
onPending(sig) {
|
|
23706
|
-
Atomics.or(
|
|
23707
|
-
Atomics.notify(
|
|
23814
|
+
Atomics.or(header4, SAB_I_SIGNALS, sigbit(sig));
|
|
23815
|
+
Atomics.notify(header4, SAB_I_SIGNALS);
|
|
23708
23816
|
},
|
|
23709
23817
|
onAsync() {
|
|
23710
|
-
for (const at of [
|
|
23818
|
+
for (const at of [header4, ...asyncFanout.get(header4) ?? []]) {
|
|
23711
23819
|
Atomics.add(at, SAB_I_ASYNC, 1);
|
|
23712
23820
|
Atomics.notify(at, SAB_I_ASYNC);
|
|
23713
23821
|
}
|
|
23714
23822
|
}
|
|
23715
23823
|
};
|
|
23716
23824
|
}
|
|
23717
|
-
function publishStops(process,
|
|
23825
|
+
function publishStops(process, header4) {
|
|
23718
23826
|
process.onState((state) => {
|
|
23719
|
-
Atomics.store(
|
|
23720
|
-
Atomics.notify(
|
|
23827
|
+
Atomics.store(header4, SAB_I_STOP, state === "stopped" ? 1 : 0);
|
|
23828
|
+
Atomics.notify(header4, SAB_I_STOP);
|
|
23721
23829
|
});
|
|
23722
23830
|
}
|
|
23723
23831
|
function transferOf(opts, lane) {
|
|
@@ -23809,7 +23917,7 @@ function linksOf(opts) {
|
|
|
23809
23917
|
function clipboardName(opts) {
|
|
23810
23918
|
return opts.program.abi === "js" ? {} : { clipboardName: opts.argv0 };
|
|
23811
23919
|
}
|
|
23812
|
-
function processOptions(opts,
|
|
23920
|
+
function processOptions(opts, header4, hooks, created4) {
|
|
23813
23921
|
return {
|
|
23814
23922
|
...inherited(opts),
|
|
23815
23923
|
...opts.owners ? { owners: true } : {},
|
|
@@ -23848,16 +23956,16 @@ function processOptions(opts, header3, hooks, created4) {
|
|
|
23848
23956
|
watches: opts.watches,
|
|
23849
23957
|
onReap: opts.onReap,
|
|
23850
23958
|
resolver: opts.resolver,
|
|
23851
|
-
...notifiers(
|
|
23852
|
-
onTimer: (which) => void Atomics.or(
|
|
23853
|
-
hasPending: () => unblocked(
|
|
23959
|
+
...notifiers(header4),
|
|
23960
|
+
onTimer: (which) => void Atomics.or(header4, SAB_I_TIMERS, 1 << which),
|
|
23961
|
+
hasPending: () => unblocked(header4) !== 0 || Atomics.load(header4, SAB_I_TIMERS) !== 0,
|
|
23854
23962
|
raise: hooks.raise,
|
|
23855
23963
|
threadKill: hooks.threadKill,
|
|
23856
23964
|
unblockedThread: hooks.unblockedThread,
|
|
23857
23965
|
...hooks.exitNow ? { exitNow: hooks.exitNow } : {},
|
|
23858
23966
|
...hooks.exitSignal ? { exitSignal: hooks.exitSignal } : {},
|
|
23859
|
-
...opts.program.abi === "wasi" || opts.program.abi === "js" ? { pendingBits: () => Atomics.load(
|
|
23860
|
-
...opts.program.abi === "wasi" ? { blockedBits: () => Atomics.load(
|
|
23967
|
+
...opts.program.abi === "wasi" || opts.program.abi === "js" ? { pendingBits: () => Atomics.load(header4, SAB_I_SIGNALS) } : {},
|
|
23968
|
+
...opts.program.abi === "wasi" ? { blockedBits: () => Atomics.load(header4, SAB_I_BLOCKED) } : {}
|
|
23861
23969
|
};
|
|
23862
23970
|
}
|
|
23863
23971
|
function threadInit(opts, program, sab, cred, thread, main) {
|
|
@@ -23923,9 +24031,9 @@ async function crashReport(process, onError, message3) {
|
|
|
23923
24031
|
function spawnWasmProcess(opts) {
|
|
23924
24032
|
const { promise: ready2, resolve: started } = readiness(opts.program.abi);
|
|
23925
24033
|
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
23926
|
-
const
|
|
24034
|
+
const header4 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
23927
24035
|
const blocked2 = opts.fork?.wasi?.blocked ?? opts.blocked;
|
|
23928
|
-
if (blocked2 && anyBlocked(blocked2) && opts.program.abi === "wasi") storeBlocked(
|
|
24036
|
+
if (blocked2 && anyBlocked(blocked2) && opts.program.abi === "wasi") storeBlocked(header4, blocked2);
|
|
23929
24037
|
const threadSignals = /* @__PURE__ */ new Map();
|
|
23930
24038
|
const created4 = new Created();
|
|
23931
24039
|
const process = new WasmProcess(
|
|
@@ -23933,7 +24041,7 @@ function spawnWasmProcess(opts) {
|
|
|
23933
24041
|
opts.fds,
|
|
23934
24042
|
processOptions(
|
|
23935
24043
|
opts,
|
|
23936
|
-
|
|
24044
|
+
header4,
|
|
23937
24045
|
{
|
|
23938
24046
|
raise: (sig, info) => signal(sig, info),
|
|
23939
24047
|
threadKill: (tid, sig) => killThread(threadSignals.get(tid), process.signalMasks().caught, sig),
|
|
@@ -23946,7 +24054,7 @@ function spawnWasmProcess(opts) {
|
|
|
23946
24054
|
created4
|
|
23947
24055
|
)
|
|
23948
24056
|
);
|
|
23949
|
-
publishStops(process,
|
|
24057
|
+
publishStops(process, header4);
|
|
23950
24058
|
const holds2 = new HeldPaths();
|
|
23951
24059
|
opts.held?.add(holds2);
|
|
23952
24060
|
const token = holdingToken(opts, holds2, {
|
|
@@ -23967,7 +24075,7 @@ function spawnWasmProcess(opts) {
|
|
|
23967
24075
|
dispatch: clocks.timed(void 0, dispatch2)
|
|
23968
24076
|
});
|
|
23969
24077
|
const lane = opts.program.abi === "js" ? openLane(token, dispatch2) : void 0;
|
|
23970
|
-
const jsThreads = jsThreadsOf(opts, process, token, dispatch2, clocks,
|
|
24078
|
+
const jsThreads = jsThreadsOf(opts, process, token, dispatch2, clocks, header4);
|
|
23971
24079
|
const { promise: exited, resolve: settle3 } = Promise.withResolvers();
|
|
23972
24080
|
let done5 = false;
|
|
23973
24081
|
const crash = new CrashSlot((message3) => crashReport(process, opts.onError, message3));
|
|
@@ -24066,7 +24174,7 @@ function spawnWasmProcess(opts) {
|
|
|
24066
24174
|
);
|
|
24067
24175
|
const terminate = (code, sig) => {
|
|
24068
24176
|
if (opts.program.abi !== "wasi" || done5) finish(code, sig);
|
|
24069
|
-
else dying.start(code, sig,
|
|
24177
|
+
else dying.start(code, sig, header4, process, () => finish(code, sig));
|
|
24070
24178
|
};
|
|
24071
24179
|
const signal = (sig, info) => {
|
|
24072
24180
|
if (process.signal(sig, info) === "terminate")
|
|
@@ -24081,16 +24189,16 @@ function spawnWasmProcess(opts) {
|
|
|
24081
24189
|
signal,
|
|
24082
24190
|
termsig: () => endedBy,
|
|
24083
24191
|
onState: (listener) => process.onState(listener),
|
|
24084
|
-
memory: () => Atomics.load(
|
|
24085
|
-
...processViews(process, opts,
|
|
24192
|
+
memory: () => Atomics.load(header4, SAB_I_MEMORY) * 65536,
|
|
24193
|
+
...processViews(process, opts, header4),
|
|
24086
24194
|
writesBack: () => opts.program.abi === "wasi" && !done5,
|
|
24087
24195
|
...clockViews(clocks)
|
|
24088
24196
|
};
|
|
24089
24197
|
}
|
|
24090
|
-
function jsThreadsOf(opts, process, token, dispatch2, clocks,
|
|
24198
|
+
function jsThreadsOf(opts, process, token, dispatch2, clocks, header4) {
|
|
24091
24199
|
if (opts.program.abi !== "js") return void 0;
|
|
24092
24200
|
const wakes = /* @__PURE__ */ new Set();
|
|
24093
|
-
asyncFanout.set(
|
|
24201
|
+
asyncFanout.set(header4, wakes);
|
|
24094
24202
|
const threads = new JsThreads({
|
|
24095
24203
|
wakes,
|
|
24096
24204
|
cap: jsThreadCap(opts.env),
|
|
@@ -24105,10 +24213,10 @@ function jsThreadsOf(opts, process, token, dispatch2, clocks, header3) {
|
|
|
24105
24213
|
process.onState((state) => threads.stopped(state === "stopped"));
|
|
24106
24214
|
return threads;
|
|
24107
24215
|
}
|
|
24108
|
-
function processViews(process, opts,
|
|
24216
|
+
function processViews(process, opts, header4) {
|
|
24109
24217
|
return {
|
|
24110
24218
|
ignoredSignals: (fork) => process.inheritable(fork),
|
|
24111
|
-
blockedSignals: () => opts.program.abi === "wasi" ? loadBlocked(
|
|
24219
|
+
blockedSignals: () => opts.program.abi === "wasi" ? loadBlocked(header4) : [0, 0],
|
|
24112
24220
|
signalMasks: () => process.signalMasks(),
|
|
24113
24221
|
umask: () => process.umask,
|
|
24114
24222
|
cred: () => copyCred(process.cred)
|
|
@@ -24666,42 +24774,398 @@ function isMessage(data) {
|
|
|
24666
24774
|
return adopt !== null && Array.isArray(adopt.records) && Array.isArray(adopt.flocks);
|
|
24667
24775
|
}
|
|
24668
24776
|
|
|
24669
|
-
// src/kernel/net/
|
|
24670
|
-
var
|
|
24671
|
-
|
|
24672
|
-
|
|
24673
|
-
|
|
24674
|
-
|
|
24675
|
-
|
|
24676
|
-
|
|
24677
|
-
|
|
24678
|
-
|
|
24679
|
-
|
|
24680
|
-
|
|
24681
|
-
|
|
24777
|
+
// src/kernel/net/dns-stub.ts
|
|
24778
|
+
var DNS_PORT = 53;
|
|
24779
|
+
var DNS_STUB_ADDRESS = "127.0.0.53";
|
|
24780
|
+
var RESOLV_CONF_PATH = "/etc/resolv.conf";
|
|
24781
|
+
var RESOLV_CONF = `nameserver ${DNS_STUB_ADDRESS}
|
|
24782
|
+
options edns0
|
|
24783
|
+
`;
|
|
24784
|
+
var DNS_STUB_TTL = 30;
|
|
24785
|
+
var DNS_FORWARD_TIMEOUT_MS = 5e3;
|
|
24786
|
+
var DNS_TCP_IDLE_MS = 1e4;
|
|
24787
|
+
var DNS_TCP_MAX = 64;
|
|
24788
|
+
var DNS_UDP_INFLIGHT = 64;
|
|
24789
|
+
var TYPE_A = 1;
|
|
24790
|
+
var TYPE_PTR = 12;
|
|
24791
|
+
var TYPE_AAAA = 28;
|
|
24792
|
+
var TYPE_OPT = 41;
|
|
24793
|
+
var CLASS_IN = 1;
|
|
24794
|
+
var NOERROR = 0;
|
|
24795
|
+
var FORMERR = 1;
|
|
24796
|
+
var SERVFAIL = 2;
|
|
24797
|
+
var NXDOMAIN = 3;
|
|
24798
|
+
var NOTIMP = 4;
|
|
24799
|
+
var QR = 32768;
|
|
24800
|
+
var AA = 1024;
|
|
24801
|
+
var TC = 512;
|
|
24802
|
+
var RD = 256;
|
|
24803
|
+
var RA = 128;
|
|
24804
|
+
var CD = 16;
|
|
24805
|
+
var UDP_PLAIN = 512;
|
|
24806
|
+
var UDP_EDNS = 1232;
|
|
24807
|
+
var UDP_MAX = 4096;
|
|
24808
|
+
var DOH_MAX = 65535;
|
|
24809
|
+
var LOCAL_ZONES = ["localhost", "slicc.internal"];
|
|
24810
|
+
var MESSAGE = "application/dns-message";
|
|
24811
|
+
var u16 = (b, at) => b[at] << 8 | b[at + 1];
|
|
24812
|
+
function skipName(b, at) {
|
|
24813
|
+
let i = at;
|
|
24814
|
+
for (let hops = 0; hops < 128; hops++) {
|
|
24815
|
+
if (i >= b.length) return void 0;
|
|
24816
|
+
const len = b[i];
|
|
24817
|
+
if (len === 0) return i + 1;
|
|
24818
|
+
if ((len & 192) === 192) return i + 2 <= b.length ? i + 2 : void 0;
|
|
24819
|
+
if (len & 192) return void 0;
|
|
24820
|
+
i += len + 1;
|
|
24821
|
+
}
|
|
24822
|
+
return void 0;
|
|
24823
|
+
}
|
|
24824
|
+
function readName(b, at) {
|
|
24825
|
+
const labels = [];
|
|
24826
|
+
let i = at;
|
|
24827
|
+
let size = 0;
|
|
24828
|
+
for (; ; ) {
|
|
24829
|
+
if (i >= b.length) return void 0;
|
|
24830
|
+
const len = b[i];
|
|
24831
|
+
if (len === 0) break;
|
|
24832
|
+
if (len & 192) return void 0;
|
|
24833
|
+
size += len + 1;
|
|
24834
|
+
if (size > 254 || i + 1 + len > b.length) return void 0;
|
|
24835
|
+
labels.push(new TextDecoder().decode(b.subarray(i + 1, i + 1 + len)));
|
|
24836
|
+
i += len + 1;
|
|
24837
|
+
}
|
|
24838
|
+
return { name: labels.join(".").toLowerCase(), end: i + 1 };
|
|
24839
|
+
}
|
|
24840
|
+
function parseQuery(b) {
|
|
24841
|
+
if (b.length < 12) return void 0;
|
|
24842
|
+
const id2 = u16(b, 0);
|
|
24843
|
+
const flags2 = u16(b, 2);
|
|
24844
|
+
if (flags2 & QR) return void 0;
|
|
24845
|
+
if (flags2 >> 11 & 15) return { ok: false, id: id2, flags: flags2, rcode: NOTIMP };
|
|
24846
|
+
if (u16(b, 4) !== 1) return { ok: false, id: id2, flags: flags2, rcode: FORMERR };
|
|
24847
|
+
const read = readName(b, 12);
|
|
24848
|
+
if (!read || read.end + 4 > b.length) return { ok: false, id: id2, flags: flags2, rcode: FORMERR };
|
|
24849
|
+
const type = u16(b, read.end);
|
|
24850
|
+
const klass = u16(b, read.end + 2);
|
|
24851
|
+
const end = read.end + 4;
|
|
24852
|
+
let edns;
|
|
24853
|
+
let at = end;
|
|
24854
|
+
const records = u16(b, 6) + u16(b, 8) + u16(b, 10);
|
|
24855
|
+
for (let n = 0; n < records; n++) {
|
|
24856
|
+
const after = skipName(b, at);
|
|
24857
|
+
if (after === void 0 || after + 10 > b.length)
|
|
24858
|
+
return { ok: false, id: id2, flags: flags2, rcode: FORMERR };
|
|
24859
|
+
if (u16(b, after) === TYPE_OPT) edns = Math.max(UDP_PLAIN, u16(b, after + 2));
|
|
24860
|
+
at = after + 10 + u16(b, after + 8);
|
|
24861
|
+
if (at > b.length) return { ok: false, id: id2, flags: flags2, rcode: FORMERR };
|
|
24862
|
+
}
|
|
24863
|
+
return { ok: true, question: { id: id2, flags: flags2, name: read.name, type, klass, end, edns } };
|
|
24864
|
+
}
|
|
24865
|
+
function encodeName(name2) {
|
|
24866
|
+
const out = [];
|
|
24867
|
+
for (const label of name2.split(".").filter(Boolean)) {
|
|
24868
|
+
const bytes = new TextEncoder().encode(label);
|
|
24869
|
+
out.push(bytes.length, ...bytes);
|
|
24870
|
+
}
|
|
24871
|
+
out.push(0);
|
|
24872
|
+
return out;
|
|
24873
|
+
}
|
|
24874
|
+
function header2(id2, flags2, counts) {
|
|
24875
|
+
const out = [id2 >> 8, id2 & 255, flags2 >> 8, flags2 & 255];
|
|
24876
|
+
for (const c of counts) out.push(c >> 8, c & 255);
|
|
24877
|
+
return out;
|
|
24878
|
+
}
|
|
24879
|
+
function opt() {
|
|
24880
|
+
return [0, 0, TYPE_OPT, UDP_EDNS >> 8, UDP_EDNS & 255, 0, 0, 0, 0, 0, 0];
|
|
24881
|
+
}
|
|
24882
|
+
function record(type, rdata) {
|
|
24883
|
+
const ttl = DNS_STUB_TTL;
|
|
24884
|
+
return [
|
|
24885
|
+
192,
|
|
24886
|
+
12,
|
|
24887
|
+
type >> 8,
|
|
24888
|
+
type & 255,
|
|
24889
|
+
0,
|
|
24890
|
+
CLASS_IN,
|
|
24891
|
+
ttl >>> 24 & 255,
|
|
24892
|
+
ttl >>> 16 & 255,
|
|
24893
|
+
ttl >>> 8 & 255,
|
|
24894
|
+
ttl & 255,
|
|
24895
|
+
rdata.length >> 8,
|
|
24896
|
+
rdata.length & 255,
|
|
24897
|
+
...rdata
|
|
24898
|
+
];
|
|
24899
|
+
}
|
|
24900
|
+
function replyFlags(query, rcode, aa) {
|
|
24901
|
+
return QR | query & 30720 | (aa ? AA : 0) | query & RD | RA | query & CD | rcode;
|
|
24902
|
+
}
|
|
24903
|
+
function answers(reply, q) {
|
|
24904
|
+
if (reply.length < 12 || !(u16(reply, 2) & QR) || u16(reply, 4) !== 1) return false;
|
|
24905
|
+
const read = readName(reply, 12);
|
|
24906
|
+
if (!read || read.end + 4 > reply.length) return false;
|
|
24907
|
+
return read.name === q.name && u16(reply, read.end) === q.type && u16(reply, read.end + 2) === q.klass;
|
|
24908
|
+
}
|
|
24909
|
+
function errorReply(id2, flags2, rcode) {
|
|
24910
|
+
return new Uint8Array(header2(id2, replyFlags(flags2, rcode, false), [0, 0, 0, 0]));
|
|
24911
|
+
}
|
|
24912
|
+
function answerReply(query, q, rcode, answers2, aa) {
|
|
24913
|
+
const extra = q.edns !== void 0 ? [opt()] : [];
|
|
24914
|
+
return new Uint8Array([
|
|
24915
|
+
...header2(q.id, replyFlags(q.flags, rcode, aa), [1, answers2.length, 0, extra.length]),
|
|
24916
|
+
...query.subarray(12, q.end),
|
|
24917
|
+
...answers2.flat(),
|
|
24918
|
+
...extra.flat()
|
|
24919
|
+
]);
|
|
24920
|
+
}
|
|
24921
|
+
function truncated(reply, q, query) {
|
|
24922
|
+
const limit = q.edns !== void 0 ? Math.min(q.edns, UDP_MAX) : UDP_PLAIN;
|
|
24923
|
+
if (reply.length <= limit) return reply;
|
|
24924
|
+
const flags2 = u16(reply, 2) | TC;
|
|
24925
|
+
const extra = q.edns !== void 0 ? [opt()] : [];
|
|
24926
|
+
return new Uint8Array([
|
|
24927
|
+
...header2(q.id, flags2, [1, 0, 0, extra.length]),
|
|
24928
|
+
...query.subarray(12, q.end),
|
|
24929
|
+
...extra.flat()
|
|
24930
|
+
]);
|
|
24931
|
+
}
|
|
24932
|
+
function ipv6Text(groups) {
|
|
24933
|
+
return groups.map((g) => g.toString(16)).join(":");
|
|
24934
|
+
}
|
|
24935
|
+
function reverseAddress(name2) {
|
|
24936
|
+
if (name2.endsWith(".in-addr.arpa")) {
|
|
24937
|
+
const parts2 = name2.slice(0, -".in-addr.arpa".length).split(".");
|
|
24938
|
+
if (parts2.length !== 4) return void 0;
|
|
24939
|
+
const text = parts2.reverse().join(".");
|
|
24940
|
+
return ipv4Bytes(text) ? text.split(".").map(Number).join(".") : void 0;
|
|
24941
|
+
}
|
|
24942
|
+
if (name2.endsWith(".ip6.arpa")) {
|
|
24943
|
+
const nibbles = name2.slice(0, -".ip6.arpa".length).split(".");
|
|
24944
|
+
if (nibbles.length !== 32 || !nibbles.every((n) => /^[0-9a-f]$/.test(n))) return void 0;
|
|
24945
|
+
const hex4 = nibbles.reverse().join("");
|
|
24946
|
+
const groups = Array.from(
|
|
24947
|
+
{ length: 8 },
|
|
24948
|
+
(_, i) => Number.parseInt(hex4.slice(i * 4, i * 4 + 4), 16)
|
|
24949
|
+
);
|
|
24950
|
+
return ipv6Text(groups);
|
|
24951
|
+
}
|
|
24952
|
+
return void 0;
|
|
24953
|
+
}
|
|
24954
|
+
function local(name2) {
|
|
24955
|
+
return LOCAL_ZONES.some((zone) => name2 === zone || name2.endsWith(`.${zone}`));
|
|
24956
|
+
}
|
|
24957
|
+
function literal(name2) {
|
|
24958
|
+
return ipv4Bytes(name2) !== void 0 || ipv6Groups(name2) !== void 0;
|
|
24959
|
+
}
|
|
24960
|
+
function addressData(address, type) {
|
|
24961
|
+
if (type === TYPE_A) return ipv4Bytes(address);
|
|
24962
|
+
const groups = type === TYPE_AAAA ? ipv6Groups(address) : void 0;
|
|
24963
|
+
return groups?.flatMap((g) => [g >> 8, g & 255]);
|
|
24964
|
+
}
|
|
24965
|
+
var DnsStub = class {
|
|
24966
|
+
resolver;
|
|
24967
|
+
forwarder;
|
|
24968
|
+
timeoutMs;
|
|
24969
|
+
constructor(options) {
|
|
24970
|
+
this.resolver = options.resolver;
|
|
24971
|
+
this.forwarder = options.forward;
|
|
24972
|
+
this.timeoutMs = options.timeoutMs ?? DNS_FORWARD_TIMEOUT_MS;
|
|
24973
|
+
}
|
|
24974
|
+
async answer(query, udp) {
|
|
24975
|
+
const parsed2 = parseQuery(query);
|
|
24976
|
+
if (!parsed2) return void 0;
|
|
24977
|
+
if (!parsed2.ok) return errorReply(parsed2.id, parsed2.flags, parsed2.rcode);
|
|
24978
|
+
const q = parsed2.question;
|
|
24979
|
+
const reply = await this.reply(query, q).catch(
|
|
24980
|
+
() => answerReply(query, q, SERVFAIL, [], false)
|
|
24981
|
+
);
|
|
24982
|
+
return udp ? truncated(reply, q, query) : reply;
|
|
24983
|
+
}
|
|
24984
|
+
async reply(query, q) {
|
|
24985
|
+
if (q.klass !== CLASS_IN || literal(q.name)) return this.forward(query, q);
|
|
24986
|
+
if (q.type === TYPE_PTR) {
|
|
24987
|
+
const address = reverseAddress(q.name);
|
|
24988
|
+
const name2 = address !== void 0 ? await this.reverse(address) : void 0;
|
|
24989
|
+
if (name2 !== void 0)
|
|
24990
|
+
return answerReply(query, q, NOERROR, [record(TYPE_PTR, encodeName(name2))], true);
|
|
24991
|
+
return this.forward(query, q);
|
|
24992
|
+
}
|
|
24993
|
+
if (q.type === TYPE_A || q.type === TYPE_AAAA) {
|
|
24994
|
+
const addresses = q.name === "" ? [] : await this.lookup(q.name);
|
|
24995
|
+
const answers2 = addresses.flatMap((a) => {
|
|
24996
|
+
const data = addressData(a, q.type);
|
|
24997
|
+
return data ? [record(q.type, data)] : [];
|
|
24998
|
+
});
|
|
24999
|
+
if (answers2.length > 0 || local(q.name) || await this.known(q.name)) {
|
|
25000
|
+
const rcode = addresses.length > 0 ? NOERROR : NXDOMAIN;
|
|
25001
|
+
return answerReply(query, q, rcode, answers2, local(q.name));
|
|
25002
|
+
}
|
|
25003
|
+
return this.forward(query, q);
|
|
25004
|
+
}
|
|
25005
|
+
if (await this.known(q.name)) return answerReply(query, q, NOERROR, [], true);
|
|
25006
|
+
if (local(q.name)) {
|
|
25007
|
+
const there = (await this.lookup(q.name)).length > 0;
|
|
25008
|
+
return answerReply(query, q, there ? NOERROR : NXDOMAIN, [], true);
|
|
24682
25009
|
}
|
|
25010
|
+
return this.forward(query, q);
|
|
24683
25011
|
}
|
|
24684
|
-
|
|
25012
|
+
lookup(name2) {
|
|
25013
|
+
return this.resolver.resolve(name2, 0).catch(() => []);
|
|
25014
|
+
}
|
|
25015
|
+
known(name2) {
|
|
25016
|
+
return this.resolver.known(name2).catch(() => false);
|
|
25017
|
+
}
|
|
25018
|
+
reverse(address) {
|
|
25019
|
+
return this.resolver.reverse(address).catch(() => void 0);
|
|
25020
|
+
}
|
|
25021
|
+
async forward(query, q) {
|
|
25022
|
+
if (!this.forwarder) return answerReply(query, q, SERVFAIL, [], false);
|
|
25023
|
+
const asked = query.slice();
|
|
25024
|
+
asked[0] = 0;
|
|
25025
|
+
asked[1] = 0;
|
|
25026
|
+
const got = await this.forwarder(asked, AbortSignal.timeout(this.timeoutMs)).catch(
|
|
25027
|
+
() => void 0
|
|
25028
|
+
);
|
|
25029
|
+
if (!got || !answers(got, q)) return answerReply(query, q, SERVFAIL, [], false);
|
|
25030
|
+
const reply = got.slice();
|
|
25031
|
+
reply[0] = q.id >> 8;
|
|
25032
|
+
reply[1] = q.id & 255;
|
|
25033
|
+
return reply;
|
|
25034
|
+
}
|
|
25035
|
+
};
|
|
25036
|
+
async function collect(body, max) {
|
|
25037
|
+
const parts2 = [];
|
|
25038
|
+
let size = 0;
|
|
25039
|
+
for await (const part of body) {
|
|
25040
|
+
size += part.length;
|
|
25041
|
+
if (size > max) return void 0;
|
|
25042
|
+
parts2.push(part);
|
|
25043
|
+
}
|
|
25044
|
+
const out = new Uint8Array(size);
|
|
25045
|
+
let at = 0;
|
|
25046
|
+
for (const part of parts2) {
|
|
25047
|
+
out.set(part, at);
|
|
25048
|
+
at += part.length;
|
|
25049
|
+
}
|
|
25050
|
+
return out;
|
|
24685
25051
|
}
|
|
24686
|
-
function
|
|
24687
|
-
|
|
24688
|
-
|
|
24689
|
-
|
|
24690
|
-
|
|
24691
|
-
|
|
24692
|
-
|
|
24693
|
-
|
|
25052
|
+
function dohForward(transport, url) {
|
|
25053
|
+
return async (query, signal) => {
|
|
25054
|
+
const res = await transport.fetch({
|
|
25055
|
+
url,
|
|
25056
|
+
method: "POST",
|
|
25057
|
+
headers: [
|
|
25058
|
+
["content-type", MESSAGE],
|
|
25059
|
+
["accept", MESSAGE]
|
|
25060
|
+
],
|
|
25061
|
+
body: query,
|
|
25062
|
+
signal
|
|
25063
|
+
});
|
|
25064
|
+
const type = res.headers.find(([k]) => k.toLowerCase() === "content-type")?.[1] ?? "";
|
|
25065
|
+
if (res.status !== 200 || type.split(";")[0].trim().toLowerCase() !== MESSAGE) {
|
|
25066
|
+
await res.cancel().catch(() => void 0);
|
|
24694
25067
|
return void 0;
|
|
24695
25068
|
}
|
|
24696
|
-
|
|
24697
|
-
|
|
24698
|
-
|
|
24699
|
-
|
|
24700
|
-
|
|
24701
|
-
|
|
24702
|
-
|
|
25069
|
+
return collect(res.body, DOH_MAX);
|
|
25070
|
+
};
|
|
25071
|
+
}
|
|
25072
|
+
function uplinkForward(uplink, server) {
|
|
25073
|
+
return async (query, signal) => {
|
|
25074
|
+
const conn = await uplink.dial({ network: "tcp", host: server, port: DNS_PORT, signal });
|
|
25075
|
+
const stop = () => conn.close();
|
|
25076
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
25077
|
+
try {
|
|
25078
|
+
await conn.write(new Uint8Array([query.length >> 8, query.length & 255, ...query]));
|
|
25079
|
+
let got = new Uint8Array();
|
|
25080
|
+
for (; ; ) {
|
|
25081
|
+
if (got.length >= 2 && got.length >= 2 + u16(got, 0)) return got.slice(2, 2 + u16(got, 0));
|
|
25082
|
+
const piece = await conn.read();
|
|
25083
|
+
if (!piece) return void 0;
|
|
25084
|
+
const next3 = new Uint8Array(got.length + piece.length);
|
|
25085
|
+
next3.set(got);
|
|
25086
|
+
next3.set(piece, got.length);
|
|
25087
|
+
got = next3;
|
|
25088
|
+
}
|
|
25089
|
+
} finally {
|
|
25090
|
+
signal.removeEventListener("abort", stop);
|
|
25091
|
+
conn.close();
|
|
25092
|
+
}
|
|
24703
25093
|
};
|
|
24704
25094
|
}
|
|
25095
|
+
function dnsForward(uplink, transport, doh) {
|
|
25096
|
+
const server = uplink?.nameserver;
|
|
25097
|
+
if (uplink && server && (ipv4Bytes(server) || ipv6Groups(server)))
|
|
25098
|
+
return uplinkForward(uplink, server);
|
|
25099
|
+
return typeof doh === "string" ? dohForward(transport, doh) : void 0;
|
|
25100
|
+
}
|
|
25101
|
+
function kernelDnsStub(resolver, transport, uplink, doh) {
|
|
25102
|
+
return new DnsStub({ resolver, forward: dnsForward(uplink, transport, doh) });
|
|
25103
|
+
}
|
|
25104
|
+
async function readExactly(conn, size, signal) {
|
|
25105
|
+
const out = new Uint8Array(size);
|
|
25106
|
+
let at = 0;
|
|
25107
|
+
while (at < size) {
|
|
25108
|
+
const piece = await conn.read(size - at, signal);
|
|
25109
|
+
if (piece.length === 0) return void 0;
|
|
25110
|
+
out.set(piece, at);
|
|
25111
|
+
at += piece.length;
|
|
25112
|
+
}
|
|
25113
|
+
return out;
|
|
25114
|
+
}
|
|
25115
|
+
async function serveTcp(stub, conn) {
|
|
25116
|
+
try {
|
|
25117
|
+
for (; ; ) {
|
|
25118
|
+
const idle2 = AbortSignal.timeout(DNS_TCP_IDLE_MS);
|
|
25119
|
+
const size = await readExactly(conn, 2, idle2);
|
|
25120
|
+
if (!size) return;
|
|
25121
|
+
const query = await readExactly(conn, u16(size, 0), idle2);
|
|
25122
|
+
if (!query) return;
|
|
25123
|
+
const reply = await stub.answer(query, false);
|
|
25124
|
+
if (!reply) return;
|
|
25125
|
+
const framed = new Uint8Array([reply.length >> 8, reply.length & 255, ...reply]);
|
|
25126
|
+
const sent = await conn.write(framed, AbortSignal.timeout(DNS_TCP_IDLE_MS));
|
|
25127
|
+
if (sent < framed.length) return;
|
|
25128
|
+
}
|
|
25129
|
+
} catch {
|
|
25130
|
+
return;
|
|
25131
|
+
} finally {
|
|
25132
|
+
conn.close();
|
|
25133
|
+
}
|
|
25134
|
+
}
|
|
25135
|
+
function enableDnsStub(net, stub) {
|
|
25136
|
+
const at = { family: "inet", host: "127.0.0.1", port: DNS_PORT };
|
|
25137
|
+
net.reserve(DNS_PORT);
|
|
25138
|
+
net.kernelOnly(DNS_PORT, true);
|
|
25139
|
+
net.activate(at, () => {
|
|
25140
|
+
const listener = net.listen(at);
|
|
25141
|
+
const open2 = /* @__PURE__ */ new Set();
|
|
25142
|
+
void (async () => {
|
|
25143
|
+
for (; ; ) {
|
|
25144
|
+
const conn = await listener.accept().catch(() => void 0);
|
|
25145
|
+
if (!conn) return;
|
|
25146
|
+
if (open2.size >= DNS_TCP_MAX) {
|
|
25147
|
+
conn.close();
|
|
25148
|
+
continue;
|
|
25149
|
+
}
|
|
25150
|
+
open2.add(conn);
|
|
25151
|
+
void serveTcp(stub, conn).finally(() => open2.delete(conn));
|
|
25152
|
+
}
|
|
25153
|
+
})();
|
|
25154
|
+
});
|
|
25155
|
+
let inflight = 0;
|
|
25156
|
+
net.serveDgram(DNS_PORT, (datagram2, to) => {
|
|
25157
|
+
if (inflight >= DNS_UDP_INFLIGHT) return;
|
|
25158
|
+
inflight++;
|
|
25159
|
+
void stub.answer(datagram2.bytes, true).then(
|
|
25160
|
+
(reply) => {
|
|
25161
|
+
if (!reply) return;
|
|
25162
|
+
const from = { family: "inet", host: to.host, port: DNS_PORT };
|
|
25163
|
+
net.deliverDgram(datagram2.from.port, { bytes: reply, from });
|
|
25164
|
+
},
|
|
25165
|
+
() => void 0
|
|
25166
|
+
).finally(() => inflight--);
|
|
25167
|
+
});
|
|
25168
|
+
}
|
|
24705
25169
|
|
|
24706
25170
|
// src/kernel/net/redirect-hops.ts
|
|
24707
25171
|
var HELD_MS = 3e4;
|
|
@@ -24709,13 +25173,13 @@ var HELD_MAX = 64;
|
|
|
24709
25173
|
var HELD_PER_OWNER = 8;
|
|
24710
25174
|
var MATCHED = ["range", "if-none-match", "if-modified-since", "if-range", "accept-encoding"];
|
|
24711
25175
|
var KERNEL = -1;
|
|
24712
|
-
function
|
|
25176
|
+
function header3(headers, name2) {
|
|
24713
25177
|
const values = headers.filter(([n]) => n.toLowerCase() === name2).map(([, v]) => v);
|
|
24714
25178
|
return values.length > 0 ? values.join(", ") : void 0;
|
|
24715
25179
|
}
|
|
24716
25180
|
function fingerprint(headers) {
|
|
24717
|
-
const fields = MATCHED.map((name2) =>
|
|
24718
|
-
return JSON.stringify([...fields,
|
|
25181
|
+
const fields = MATCHED.map((name2) => header3(headers, name2) ?? "");
|
|
25182
|
+
return JSON.stringify([...fields, header3(headers, "authorization") !== void 0]);
|
|
24719
25183
|
}
|
|
24720
25184
|
function unauthorized(print) {
|
|
24721
25185
|
return JSON.stringify([...JSON.parse(print).slice(0, -1), false]);
|
|
@@ -24758,7 +25222,7 @@ function replayingHops(inner, heldMs = HELD_MS) {
|
|
|
24758
25222
|
};
|
|
24759
25223
|
const replay = (chain2) => {
|
|
24760
25224
|
const [hop, ...rest2] = chain2.hops;
|
|
24761
|
-
const location = hop &&
|
|
25225
|
+
const location = hop && header3(hop.headers, "location");
|
|
24762
25226
|
if (!hop || location === void 0) return chain2.final;
|
|
24763
25227
|
const target = new URL(location, hop.url);
|
|
24764
25228
|
target.hash = "";
|
|
@@ -24883,7 +25347,7 @@ function materializable(req) {
|
|
|
24883
25347
|
if (req.shellGrants !== true && !isStrings(req.names)) return false;
|
|
24884
25348
|
return isStrings(req.argv) && typeof req.path === "string" && typeof req.cwd === "string";
|
|
24885
25349
|
}
|
|
24886
|
-
function
|
|
25350
|
+
function errorReply2(code, message3) {
|
|
24887
25351
|
return { v: 1, error: { code, message: message3 } };
|
|
24888
25352
|
}
|
|
24889
25353
|
function isRecord(value2) {
|
|
@@ -24895,9 +25359,9 @@ function serialized(reply) {
|
|
|
24895
25359
|
const text = JSON.stringify(reply);
|
|
24896
25360
|
plain3 = text === void 0 ? void 0 : JSON.parse(text);
|
|
24897
25361
|
} catch (err) {
|
|
24898
|
-
return JSON.stringify(
|
|
25362
|
+
return JSON.stringify(errorReply2("EIO", lineOf2(err)));
|
|
24899
25363
|
}
|
|
24900
|
-
if (!isRecord(plain3)) return JSON.stringify(
|
|
25364
|
+
if (!isRecord(plain3)) return JSON.stringify(errorReply2("EIO", "the vault gave no reply"));
|
|
24901
25365
|
const { v: _, ...rest2 } = plain3;
|
|
24902
25366
|
return JSON.stringify({ v: 1, ...rest2 });
|
|
24903
25367
|
}
|
|
@@ -24945,18 +25409,18 @@ var SealedChannel = class {
|
|
|
24945
25409
|
}
|
|
24946
25410
|
async answer(req, signal) {
|
|
24947
25411
|
const hook = this.broker.hook;
|
|
24948
|
-
if (!hook) return
|
|
25412
|
+
if (!hook) return errorReply2("ENOTCONN", "no vault is connected");
|
|
24949
25413
|
const stopped = new Promise((resolve2) => {
|
|
24950
25414
|
signal.addEventListener("abort", () => resolve2(void 0), { once: true });
|
|
24951
25415
|
});
|
|
24952
25416
|
if (signal.aborted) return void 0;
|
|
24953
25417
|
const asked = Promise.resolve().then(() => hook(req, { signal })).then(
|
|
24954
|
-
(reply2) => isRecord(reply2) ? reply2 :
|
|
24955
|
-
(err) =>
|
|
25418
|
+
(reply2) => isRecord(reply2) ? reply2 : errorReply2("EIO", "the vault gave no reply"),
|
|
25419
|
+
(err) => errorReply2("EIO", lineOf2(err))
|
|
24956
25420
|
);
|
|
24957
25421
|
const reply = await Promise.race([asked, stopped]);
|
|
24958
25422
|
if (!signal.aborted) return reply;
|
|
24959
|
-
return signal.reason === "timeout" ?
|
|
25423
|
+
return signal.reason === "timeout" ? errorReply2("ETIMEDOUT", "the vault did not answer within 10 s") : void 0;
|
|
24960
25424
|
}
|
|
24961
25425
|
drop() {
|
|
24962
25426
|
this.reply?.fill(0);
|
|
@@ -27302,6 +27766,10 @@ function blobModuleUrl(source) {
|
|
|
27302
27766
|
const url = URL.createObjectURL(new Blob([source], { type: "text/javascript" }));
|
|
27303
27767
|
return { url, revoke: () => URL.revokeObjectURL(url) };
|
|
27304
27768
|
}
|
|
27769
|
+
function describe(req, tty) {
|
|
27770
|
+
const exe = req.exe === void 0 ? {} : { exe: req.exe };
|
|
27771
|
+
return { argv: [req.argv0, ...req.args], tty, started: Date.now(), ...exe };
|
|
27772
|
+
}
|
|
27305
27773
|
function linksOf2(req) {
|
|
27306
27774
|
return req.links === void 0 ? {} : { links: req.links };
|
|
27307
27775
|
}
|
|
@@ -27323,6 +27791,7 @@ var LAYOUT = [
|
|
|
27323
27791
|
["/etc", 493],
|
|
27324
27792
|
[PASSWD, 420],
|
|
27325
27793
|
[GROUP, 420],
|
|
27794
|
+
[RESOLV_CONF_PATH, 420],
|
|
27326
27795
|
["/usr", 493],
|
|
27327
27796
|
["/usr/local", 493]
|
|
27328
27797
|
];
|
|
@@ -27665,6 +28134,10 @@ var Launcher = class {
|
|
|
27665
28134
|
roots: packageTlsRoots(this.verifiedFs(options.fs), this.modulesDir),
|
|
27666
28135
|
ca: this.ca
|
|
27667
28136
|
});
|
|
28137
|
+
enableDnsStub(
|
|
28138
|
+
this.net,
|
|
28139
|
+
kernelDnsStub(this.resolver, this.transport, options.uplink, options.doh)
|
|
28140
|
+
);
|
|
27668
28141
|
enableCdp(this.net, this.cdp);
|
|
27669
28142
|
this.facades.enable(this.net);
|
|
27670
28143
|
const fs = this.commandFs(this.base);
|
|
@@ -27752,10 +28225,10 @@ var Launcher = class {
|
|
|
27752
28225
|
ready: () => this.fstab,
|
|
27753
28226
|
lookup: (name2) => this.users.lookup(name2),
|
|
27754
28227
|
watch: async (paths, notify) => {
|
|
27755
|
-
const
|
|
28228
|
+
const local2 = this.watchers.watch(paths, { recursive: true }, () => notify());
|
|
27756
28229
|
const remote = await this.watchFiles(paths, notify);
|
|
27757
28230
|
return () => {
|
|
27758
|
-
|
|
28231
|
+
local2();
|
|
27759
28232
|
remote();
|
|
27760
28233
|
};
|
|
27761
28234
|
},
|
|
@@ -27941,7 +28414,7 @@ var Launcher = class {
|
|
|
27941
28414
|
abi: "wasi",
|
|
27942
28415
|
glue,
|
|
27943
28416
|
wasm: glue,
|
|
27944
|
-
argv0
|
|
28417
|
+
argv0,
|
|
27945
28418
|
...asked
|
|
27946
28419
|
};
|
|
27947
28420
|
}
|
|
@@ -28483,7 +28956,18 @@ var Launcher = class {
|
|
|
28483
28956
|
const handle = await this.admitted(
|
|
28484
28957
|
program.abi !== "js",
|
|
28485
28958
|
req.fds,
|
|
28486
|
-
(fds, quietOom) => this.start({
|
|
28959
|
+
(fds, quietOom) => this.start({
|
|
28960
|
+
...req,
|
|
28961
|
+
fds,
|
|
28962
|
+
quietOom,
|
|
28963
|
+
cwd,
|
|
28964
|
+
program,
|
|
28965
|
+
argv0: target.argv0,
|
|
28966
|
+
exe: target.copy ?? target.glue,
|
|
28967
|
+
args,
|
|
28968
|
+
env,
|
|
28969
|
+
cwdSlot
|
|
28970
|
+
})
|
|
28487
28971
|
).finally(() => this.cwds.release(cwdSlot));
|
|
28488
28972
|
void handle.exited.finally(done5);
|
|
28489
28973
|
return handle;
|
|
@@ -28675,11 +29159,7 @@ var Launcher = class {
|
|
|
28675
29159
|
if (req.pgid !== void 0) this.jobs.join(pid, req.pgid);
|
|
28676
29160
|
if (req.group === "lead") this.jobs.lead(pid);
|
|
28677
29161
|
if (req.group === "session") this.jobs.setsid(pid);
|
|
28678
|
-
this.described.set(pid,
|
|
28679
|
-
argv: [req.argv0, ...req.args],
|
|
28680
|
-
tty: terminal?.name ?? null,
|
|
28681
|
-
started: Date.now()
|
|
28682
|
-
});
|
|
29162
|
+
this.described.set(pid, describe(req, terminal?.name ?? null));
|
|
28683
29163
|
handle.onState(
|
|
28684
29164
|
(state) => state === "stopped" ? this.stopped.add(pid) : this.stopped.delete(pid)
|
|
28685
29165
|
);
|
|
@@ -29287,6 +29767,19 @@ var Launcher = class {
|
|
|
29287
29767
|
inUse(path) {
|
|
29288
29768
|
return [...this.openFiles].some((nodes) => nodes.holds(path)) || heldUnder(this.held, path);
|
|
29289
29769
|
}
|
|
29770
|
+
async resolvConf() {
|
|
29771
|
+
if (isProtected(this.prefixes, RESOLV_CONF_PATH)) return;
|
|
29772
|
+
try {
|
|
29773
|
+
const there = await this.base.lstat(RESOLV_CONF_PATH).then(
|
|
29774
|
+
() => true,
|
|
29775
|
+
() => false
|
|
29776
|
+
);
|
|
29777
|
+
if (there) return;
|
|
29778
|
+
await this.base.writeFile(RESOLV_CONF_PATH, RESOLV_CONF);
|
|
29779
|
+
} catch {
|
|
29780
|
+
return;
|
|
29781
|
+
}
|
|
29782
|
+
}
|
|
29290
29783
|
async stampLayout() {
|
|
29291
29784
|
const layout = [
|
|
29292
29785
|
...LAYOUT,
|
|
@@ -29422,6 +29915,7 @@ var Launcher = class {
|
|
|
29422
29915
|
await this.mountShm();
|
|
29423
29916
|
await this.pnpmReady();
|
|
29424
29917
|
await this.users.ensure();
|
|
29918
|
+
await this.resolvConf();
|
|
29425
29919
|
if (this.owners) await this.stampLayout();
|
|
29426
29920
|
if (this.owners) await this.sudoer.provision();
|
|
29427
29921
|
await writeCaFile(this.base, this.ca).catch(() => void 0);
|
|
@@ -29660,12 +30154,12 @@ var Launcher = class {
|
|
|
29660
30154
|
const out = [];
|
|
29661
30155
|
const err = [];
|
|
29662
30156
|
const keep2 = options.collect !== false;
|
|
29663
|
-
const
|
|
30157
|
+
const collect2 = (chunks, tee) => (bytes) => {
|
|
29664
30158
|
if (keep2) chunks.push(bytes);
|
|
29665
30159
|
tee?.(bytes);
|
|
29666
30160
|
};
|
|
29667
|
-
const stdout =
|
|
29668
|
-
const stderr =
|
|
30161
|
+
const stdout = collect2(out, options.onStdout);
|
|
30162
|
+
const stderr = collect2(err, options.onStderr);
|
|
29669
30163
|
const report = (message3) => stderr(encoder10.encode(`${message3}
|
|
29670
30164
|
`));
|
|
29671
30165
|
if (!planned) {
|
|
@@ -30083,7 +30577,14 @@ function facadesOption(req, port) {
|
|
|
30083
30577
|
function remotes(port, req) {
|
|
30084
30578
|
return {
|
|
30085
30579
|
...req.transport ? { transport: new RemoteTransport(port, req.transport) } : {},
|
|
30086
|
-
...req.uplink ? {
|
|
30580
|
+
...req.uplink ? {
|
|
30581
|
+
uplink: new RemoteUplink(
|
|
30582
|
+
port,
|
|
30583
|
+
req.uplink.traits,
|
|
30584
|
+
req.uplink.routes,
|
|
30585
|
+
req.uplink.nameserver
|
|
30586
|
+
)
|
|
30587
|
+
} : {}
|
|
30087
30588
|
};
|
|
30088
30589
|
}
|
|
30089
30590
|
function dial(l, req) {
|
|
@@ -30181,6 +30682,7 @@ function hostOptions(req, port, sealed, clipboard, lookup2) {
|
|
|
30181
30682
|
return {
|
|
30182
30683
|
cron: { lock: `slicc-kernel-cron:${req.metadata ?? META_DB}` },
|
|
30183
30684
|
...req.hostname !== void 0 ? { hostname: req.hostname } : {},
|
|
30685
|
+
...req.doh !== void 0 ? { doh: req.doh } : {},
|
|
30184
30686
|
...req.users !== void 0 ? { users: req.users } : {},
|
|
30185
30687
|
...req.denials ? { onDenial: (denial) => port.postMessage({ denial }) } : {},
|
|
30186
30688
|
...req.protect ? { protect: hostProtect(req.protect, lookup2) } : {},
|