@walkhi/code-relax 0.1.0-beta.24 → 0.1.0-beta.25
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.
|
@@ -56,7 +56,7 @@ const relay = await startSelfRelay({ port, hostKey, stateFile, mysqlConfigFile,
|
|
|
56
56
|
usageDiagnosticKeyFile: process.env.RELAY_USAGE_DIAGNOSTIC_KEY_FILE,
|
|
57
57
|
publicRelayUrl: process.env.RELAY_PUBLIC_URL || serviceEndpoints.relayUrl, appDownloadUrl: process.env.RELAY_APP_DOWNLOAD_URL || serviceEndpoints.installUrl,
|
|
58
58
|
log: entry => console.log(JSON.stringify({ time: new Date().toISOString(), ...entry })) });
|
|
59
|
-
console.log(JSON.stringify({ service: 'codex-self-relay', listen: relay.url, maxConnections:
|
|
59
|
+
console.log(JSON.stringify({ service: 'codex-self-relay', listen: relay.url, maxConnections: 128, maxRelaySessions,
|
|
60
60
|
maxFrameMiB: 8, encryption: 'TLS must be supplied by reverse proxy; no end-to-end encryption' }));
|
|
61
61
|
await new Promise(resolve => { process.once('SIGTERM', resolve); process.once('SIGINT', resolve); });
|
|
62
62
|
await relay.close();
|
|
@@ -16,7 +16,7 @@ import { relayDiagnostics } from './diagnostics.mjs';
|
|
|
16
16
|
|
|
17
17
|
// Always loopback; a TLS reverse proxy supplies the private-trial Internet endpoint.
|
|
18
18
|
export async function startSelfRelay({ port = 0, hostKey = secret(), pairingTtlMs = 120000,
|
|
19
|
-
maxConnections =
|
|
19
|
+
maxConnections = 128, maxClientsPerHost = 16, maxPayload = 8 * 1024 * 1024, stateFile,
|
|
20
20
|
maxRelaySessions = 8, adminStateFile, mysqlConfigFile, accountConfigFile, usageDiagnosticKeyFile,
|
|
21
21
|
publicRelayUrl = '', appDownloadUrl = '', debugAllowlistFile, log = () => {} } = {}) {
|
|
22
22
|
if (!validSecret(hostKey)) throw new Error('Invalid host credential');
|
|
@@ -46,18 +46,34 @@ export async function startSelfRelay({ port = 0, hostKey = secret(), pairingTtlM
|
|
|
46
46
|
let activeRelaySessions = 0;
|
|
47
47
|
for (const record of store.entries()) rooms.set(record.id, { ...record, durable: true, connections: new Map(), observers: new Map(), uploadClients: new Map() });
|
|
48
48
|
let commitTail = Promise.resolve();
|
|
49
|
+
function queueStore(operation) {
|
|
50
|
+
const pending = commitTail.then(operation);
|
|
51
|
+
commitTail = pending.catch(() => {});
|
|
52
|
+
return pending;
|
|
53
|
+
}
|
|
49
54
|
function commit(room, changes) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
return queueStore(async () => {
|
|
56
|
+
changes = typeof changes === 'function' ? changes(room) : changes;
|
|
57
|
+
const next = { ...room, ...changes, updatedAt: new Date().toISOString() };
|
|
58
|
+
if (room.durable) {
|
|
59
|
+
const { id, hostHash, clients, revision, status, createdAt, updatedAt, officialComputer } = next;
|
|
60
|
+
await store.save({ id, hostHash, clients, revision, status, createdAt, updatedAt, ...(officialComputer ? { officialComputer } : {}) });
|
|
61
|
+
}
|
|
62
|
+
Object.assign(room, changes, { updatedAt: next.updatedAt });
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function registerRoom(id, durable, credential) {
|
|
66
|
+
return queueStore(async () => {
|
|
67
|
+
// Resolve concurrent first connections before writing the device identity.
|
|
68
|
+
if (durable && rooms.has(id)) return rooms.get(id);
|
|
69
|
+
const now = new Date().toISOString();
|
|
70
|
+
const record = { id, revision: 0, status: 'active', clients: [], createdAt: now, updatedAt: now,
|
|
71
|
+
...(durable ? { hostHash: digest(credential) } : {}) };
|
|
72
|
+
if (durable) await store.save(record);
|
|
73
|
+
const room = { ...record, durable, connections: new Map(), observers: new Map(), uploadClients: new Map() };
|
|
74
|
+
rooms.set(id, room);
|
|
75
|
+
return room;
|
|
58
76
|
});
|
|
59
|
-
commitTail = operation.catch(() => {});
|
|
60
|
-
return operation;
|
|
61
77
|
}
|
|
62
78
|
function invitation(room) {
|
|
63
79
|
const code = secret(); room.pairingHash = digest(code); room.expires = Date.now() + pairingTtlMs;
|
|
@@ -298,7 +314,7 @@ export async function startSelfRelay({ port = 0, hostKey = secret(), pairingTtlM
|
|
|
298
314
|
socket.end('HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n'); return;
|
|
299
315
|
}
|
|
300
316
|
if (Date.now() - admissionStart >= 60000) { admissionStart = Date.now(); admissions = 0; }
|
|
301
|
-
if (wss.clients.size >= maxConnections || ++admissions >
|
|
317
|
+
if (wss.clients.size >= maxConnections || ++admissions > 240) {
|
|
302
318
|
socket.end('HTTP/1.1 429 Too Many Requests\r\nConnection: close\r\n\r\n'); return;
|
|
303
319
|
}
|
|
304
320
|
wss.handleUpgrade(request, socket, head, ws => wss.emit('connection', ws));
|
|
@@ -435,18 +451,12 @@ export async function startSelfRelay({ port = 0, hostKey = secret(), pairingTtlM
|
|
|
435
451
|
}
|
|
436
452
|
catch { return fail(1008, 'Invalid LAN candidates'); }
|
|
437
453
|
room = durable ? rooms.get(message.deviceId) : undefined;
|
|
438
|
-
if (room && (room.status !== 'active' || !matches(message.deviceSecret, room.hostHash))) return fail();
|
|
439
454
|
if (!room) {
|
|
440
|
-
// Durable computers prove future ownership with their generated device secret.
|
|
441
|
-
// The legacy deployment key remains accepted, but is no longer required for first registration.
|
|
442
455
|
if (!durable && !matches(message.key, hostHash)) return fail();
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
room = { id: durable ? message.deviceId : randomUUID(), durable,
|
|
446
|
-
revision: 0, status: 'active', clients: [], connections: new Map(), observers: new Map(), uploadClients: new Map(), createdAt: now, updatedAt: now,
|
|
447
|
-
...(durable ? { hostHash: digest(message.deviceSecret) } : {}) };
|
|
448
|
-
await commit(room, {}); rooms.set(room.id, room);
|
|
456
|
+
room = await registerRoom(durable ? message.deviceId : randomUUID(), durable, message.deviceSecret);
|
|
457
|
+
if (ws.readyState !== ws.OPEN) return;
|
|
449
458
|
}
|
|
459
|
+
if (durable && (room.status !== 'active' || !matches(message.deviceSecret, room.hostHash))) return fail();
|
|
450
460
|
const oldHost = room.host;
|
|
451
461
|
room.observers ||= new Map();
|
|
452
462
|
if (oldHost && oldHost !== ws) {
|
|
@@ -490,6 +500,7 @@ export async function startSelfRelay({ port = 0, hostKey = secret(), pairingTtlM
|
|
|
490
500
|
await commit(room, current => ({ clients: [...current.clients.filter(item => item.id !== clientId), client], revision: current.revision + 1 }));
|
|
491
501
|
room.pairingHash = undefined;
|
|
492
502
|
} finally { room.pairingInProgress = false; }
|
|
503
|
+
if (!room.host) return fail(4410, 'Computer offline; authorization retained');
|
|
493
504
|
send(room.host, { type: 'authorization-changed', clients: room.clients, revision: room.revision });
|
|
494
505
|
} else {
|
|
495
506
|
clientId = message.clientId;
|