@serfab/cadre-host 1.13.0 → 1.15.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 +347 -423
- package/dist/bin/host.d.ts +6 -3
- package/dist/bin/host.js +332 -524
- package/dist/bin/host.js.map +1 -1
- package/dist/bin/join-output.d.ts +56 -0
- package/dist/bin/join-output.js +92 -0
- package/dist/bin/join-output.js.map +1 -0
- package/dist/bin/nat-output.d.ts +54 -0
- package/dist/bin/nat-output.js +138 -0
- package/dist/bin/nat-output.js.map +1 -0
- package/dist/bin/ui-access.d.ts +22 -0
- package/dist/bin/ui-access.js +44 -0
- package/dist/bin/ui-access.js.map +1 -0
- package/dist/hosted/claim-details.d.ts +66 -0
- package/dist/hosted/claim-details.js +60 -0
- package/dist/hosted/claim-details.js.map +1 -0
- package/dist/hosted/hosted-node-service.d.ts +325 -0
- package/dist/hosted/hosted-node-service.js +678 -0
- package/dist/hosted/hosted-node-service.js.map +1 -0
- package/dist/hosted/hosted-node-store.d.ts +40 -0
- package/dist/hosted/hosted-node-store.js +126 -0
- package/dist/hosted/hosted-node-store.js.map +1 -0
- package/dist/{donation/donation-supervisor.d.ts → hosted/hosted-node-supervisor.d.ts} +70 -53
- package/dist/hosted/hosted-node-supervisor.js +396 -0
- package/dist/hosted/hosted-node-supervisor.js.map +1 -0
- package/dist/hosted/hosted-node-watcher.d.ts +95 -0
- package/dist/hosted/hosted-node-watcher.js +260 -0
- package/dist/hosted/hosted-node-watcher.js.map +1 -0
- package/dist/hosted/index.d.ts +16 -0
- package/dist/hosted/index.js +13 -0
- package/dist/hosted/index.js.map +1 -0
- package/dist/hosted/node-status.d.ts +51 -0
- package/dist/hosted/node-status.js +77 -0
- package/dist/hosted/node-status.js.map +1 -0
- package/dist/hosted/types.d.ts +141 -0
- package/dist/hosted/types.js +22 -0
- package/dist/hosted/types.js.map +1 -0
- package/dist/index.d.ts +12 -24
- package/dist/index.js +9 -19
- package/dist/index.js.map +1 -1
- package/dist/installer/config.d.ts +27 -34
- package/dist/installer/config.js +46 -15
- package/dist/installer/config.js.map +1 -1
- package/dist/installer/index.d.ts +9 -19
- package/dist/installer/index.js +21 -85
- package/dist/installer/index.js.map +1 -1
- package/dist/installer/paths.d.ts +0 -2
- package/dist/installer/paths.js +0 -4
- package/dist/installer/paths.js.map +1 -1
- package/dist/installer/wizard.d.ts +12 -9
- package/dist/installer/wizard.js +15 -14
- package/dist/installer/wizard.js.map +1 -1
- package/dist/nat/address-resolver.d.ts +18 -17
- package/dist/nat/address-resolver.js +79 -25
- package/dist/nat/address-resolver.js.map +1 -1
- package/dist/nat/address-watch.d.ts +37 -0
- package/dist/nat/address-watch.js +84 -0
- package/dist/nat/address-watch.js.map +1 -0
- package/dist/nat/ddns/duckdns.d.ts +2 -1
- package/dist/nat/ddns/duckdns.js +5 -1
- package/dist/nat/ddns/duckdns.js.map +1 -1
- package/dist/nat/ddns/index.d.ts +6 -0
- package/dist/nat/ddns/index.js.map +1 -1
- package/dist/nat/index.d.ts +13 -9
- package/dist/nat/index.js +7 -5
- package/dist/nat/index.js.map +1 -1
- package/dist/nat/nat-service.d.ts +220 -77
- package/dist/nat/nat-service.js +653 -239
- package/dist/nat/nat-service.js.map +1 -1
- package/dist/nat/nat-store.d.ts +12 -5
- package/dist/nat/nat-store.js +124 -29
- package/dist/nat/nat-store.js.map +1 -1
- package/dist/nat/network-mode.d.ts +19 -0
- package/dist/nat/network-mode.js +32 -0
- package/dist/nat/network-mode.js.map +1 -0
- package/dist/nat/port-mapper.d.ts +83 -79
- package/dist/nat/port-mapper.js +148 -189
- package/dist/nat/port-mapper.js.map +1 -1
- package/dist/nat/reachability.d.ts +32 -15
- package/dist/nat/reachability.js +110 -22
- package/dist/nat/reachability.js.map +1 -1
- package/dist/nat/types.d.ts +98 -27
- package/dist/nat/types.js +8 -5
- package/dist/nat/types.js.map +1 -1
- package/dist/orchestrator/host-process-orchestrator.d.ts +32 -74
- package/dist/orchestrator/host-process-orchestrator.js +84 -233
- package/dist/orchestrator/host-process-orchestrator.js.map +1 -1
- package/dist/{installer/identity.d.ts → orchestrator/identity-file.d.ts} +5 -5
- package/dist/{installer/identity.js → orchestrator/identity-file.js} +6 -6
- package/dist/orchestrator/identity-file.js.map +1 -0
- package/dist/orchestrator/index.d.ts +2 -3
- package/dist/orchestrator/index.js +1 -1
- package/dist/orchestrator/index.js.map +1 -1
- package/dist/orchestrator/node-identity.d.ts +6 -6
- package/dist/orchestrator/node-identity.js +7 -7
- package/dist/orchestrator/node-identity.js.map +1 -1
- package/dist/orchestrator/port-allocator.d.ts +5 -6
- package/dist/orchestrator/port-allocator.js +9 -11
- package/dist/orchestrator/port-allocator.js.map +1 -1
- package/dist/orchestrator/state-store.d.ts +3 -5
- package/dist/orchestrator/state-store.js +2 -10
- package/dist/orchestrator/state-store.js.map +1 -1
- package/dist/orchestrator/types.d.ts +33 -22
- package/dist/orchestrator/types.js.map +1 -1
- package/dist/package-version.d.ts +1 -0
- package/dist/package-version.js +4 -0
- package/dist/package-version.js.map +1 -0
- package/dist/server/error-handler.d.ts +5 -25
- package/dist/server/error-handler.js +11 -74
- package/dist/server/error-handler.js.map +1 -1
- package/dist/server/events/types.d.ts +7 -11
- package/dist/server/events/types.js +2 -1
- package/dist/server/events/types.js.map +1 -1
- package/dist/server/index.d.ts +11 -37
- package/dist/server/index.js +30 -48
- package/dist/server/index.js.map +1 -1
- package/dist/server/routes/hosted-nodes.d.ts +28 -0
- package/dist/server/routes/hosted-nodes.js +68 -0
- package/dist/server/routes/hosted-nodes.js.map +1 -0
- package/dist/server/routes/nat.d.ts +4 -1
- package/dist/server/routes/nat.js +13 -2
- package/dist/server/routes/nat.js.map +1 -1
- package/dist/server/routes/nodes.d.ts +6 -20
- package/dist/server/routes/nodes.js +7 -86
- package/dist/server/routes/nodes.js.map +1 -1
- package/dist/server/routes/settings.d.ts +3 -7
- package/dist/server/routes/settings.js +18 -8
- package/dist/server/routes/settings.js.map +1 -1
- package/dist/server/routes/status.d.ts +2 -25
- package/dist/server/routes/status.js +3 -43
- package/dist/server/routes/status.js.map +1 -1
- package/dist/server/server.js +8 -8
- package/dist/server/settings-store.d.ts +2 -2
- package/dist/server/settings-store.js +2 -2
- package/dist/server/static.js +1 -2
- package/dist/server/static.js.map +1 -1
- package/dist/ui/assets/index-BHd8CWZA.css +1 -0
- package/dist/ui/assets/index-Ccr2GjPT.js +23 -0
- package/dist/ui/assets/index-Ccr2GjPT.js.map +1 -0
- package/dist/ui/index.html +2 -2
- package/dist/update/index.d.ts +2 -2
- package/dist/update/index.js +2 -2
- package/dist/update/store.d.ts +1 -1
- package/dist/update/store.js +1 -1
- package/dist/update/types.d.ts +1 -1
- package/dist/update/types.js +1 -1
- package/package.json +5 -7
- package/src/__tests__/cli-nat.smoke.test.ts +219 -212
- package/src/__tests__/cli.smoke.test.ts +2 -2
- package/src/__tests__/global-setup.ts +2 -3
- package/src/__tests__/orchestrator-claim-secret.test.ts +111 -0
- package/src/__tests__/orchestrator-env-scrub.test.ts +160 -163
- package/src/__tests__/orchestrator-handle-contract.ts +134 -134
- package/src/__tests__/orchestrator-node-identity.test.ts +177 -203
- package/src/__tests__/orchestrator-ports.test.ts +124 -143
- package/src/__tests__/orchestrator-push.test.ts +138 -146
- package/src/__tests__/orchestrator.test.ts +1017 -1063
- package/src/__tests__/ui-access.test.ts +30 -0
- package/src/bin/host.ts +397 -572
- package/src/bin/join-output.ts +120 -0
- package/src/bin/nat-output.ts +188 -0
- package/src/bin/ui-access.ts +50 -0
- package/src/{donation → hosted}/__tests__/fake-orchestrator.test.ts +172 -173
- package/src/{donation → hosted}/__tests__/fake-orchestrator.ts +43 -23
- package/src/hosted/__tests__/hosted-node-service.test.ts +708 -0
- package/src/hosted/__tests__/hosted-node-supervisor.test.ts +475 -0
- package/src/hosted/__tests__/test-invitation.ts +33 -0
- package/src/hosted/claim-details.ts +103 -0
- package/src/hosted/hosted-node-service.ts +814 -0
- package/src/hosted/hosted-node-store.ts +144 -0
- package/src/hosted/hosted-node-supervisor.ts +439 -0
- package/src/hosted/hosted-node-watcher.ts +288 -0
- package/src/hosted/index.ts +53 -0
- package/src/hosted/node-status.ts +97 -0
- package/src/hosted/types.ts +160 -0
- package/src/index.ts +72 -91
- package/src/installer/__tests__/config.test.ts +15 -40
- package/src/installer/__tests__/installer.smoke.test.ts +184 -263
- package/src/installer/__tests__/wizard.test.ts +25 -13
- package/src/installer/config.ts +201 -175
- package/src/installer/index.ts +252 -327
- package/src/installer/paths.ts +104 -109
- package/src/installer/wizard.ts +24 -26
- package/src/nat/__tests__/address-resolver.test.ts +107 -82
- package/src/nat/__tests__/nat-service.test.ts +608 -515
- package/src/nat/__tests__/nat-store.test.ts +49 -12
- package/src/nat/__tests__/network-mode.test.ts +38 -0
- package/src/nat/__tests__/port-mapper.test.ts +30 -191
- package/src/nat/__tests__/reachability.test.ts +96 -13
- package/src/nat/address-resolver.ts +94 -52
- package/src/nat/address-watch.ts +92 -0
- package/src/nat/ddns/duckdns.ts +5 -1
- package/src/nat/ddns/index.ts +6 -0
- package/src/nat/index.ts +33 -13
- package/src/nat/nat-service.ts +942 -501
- package/src/nat/nat-store.ts +126 -31
- package/src/nat/network-mode.ts +36 -0
- package/src/nat/port-mapper.ts +241 -329
- package/src/nat/reachability.ts +155 -34
- package/src/nat/types.ts +110 -37
- package/src/{installer/__tests__/identity.test.ts → orchestrator/__tests__/identity-file.test.ts} +34 -34
- package/src/orchestrator/__tests__/node-identity.test.ts +62 -62
- package/src/orchestrator/host-process-orchestrator.ts +1089 -1260
- package/src/{installer/identity.ts → orchestrator/identity-file.ts} +56 -56
- package/src/orchestrator/index.ts +9 -10
- package/src/orchestrator/node-identity.ts +41 -41
- package/src/orchestrator/port-allocator.ts +71 -73
- package/src/orchestrator/state-store.ts +76 -90
- package/src/orchestrator/types.ts +34 -23
- package/src/package-version.ts +4 -0
- package/src/server/__tests__/bus.test.ts +38 -38
- package/src/server/__tests__/error-handler.test.ts +81 -118
- package/src/server/__tests__/fakes.ts +15 -18
- package/src/server/__tests__/hosted-nodes-route.test.ts +161 -0
- package/src/server/__tests__/nodes-route.test.ts +114 -283
- package/src/server/__tests__/publishers.test.ts +193 -180
- package/src/server/__tests__/server.smoke.test.ts +134 -223
- package/src/server/__tests__/settings-route.test.ts +210 -195
- package/src/server/__tests__/sse-route.test.ts +119 -119
- package/src/server/__tests__/status-route.test.ts +82 -121
- package/src/server/error-handler.ts +112 -178
- package/src/server/events/types.ts +20 -24
- package/src/server/index.ts +223 -267
- package/src/server/routes/hosted-nodes.ts +83 -0
- package/src/server/routes/nat.ts +75 -63
- package/src/server/routes/nodes.ts +96 -188
- package/src/server/routes/settings.ts +20 -15
- package/src/server/routes/status.ts +5 -67
- package/src/server/server.ts +8 -8
- package/src/server/settings-store.ts +2 -2
- package/src/server/static.ts +1 -2
- package/src/update/index.ts +2 -2
- package/src/update/store.ts +1 -1
- package/src/update/types.ts +1 -1
- package/dist/auth/duration.d.ts +0 -1
- package/dist/auth/duration.js +0 -32
- package/dist/auth/duration.js.map +0 -1
- package/dist/auth/index.d.ts +0 -11
- package/dist/auth/index.js +0 -9
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/self-label.d.ts +0 -36
- package/dist/auth/self-label.js +0 -57
- package/dist/auth/self-label.js.map +0 -1
- package/dist/auth/trust-circle-store.d.ts +0 -26
- package/dist/auth/trust-circle-store.js +0 -129
- package/dist/auth/trust-circle-store.js.map +0 -1
- package/dist/auth/trust-circle.d.ts +0 -156
- package/dist/auth/trust-circle.js +0 -307
- package/dist/auth/trust-circle.js.map +0 -1
- package/dist/auth/types.d.ts +0 -84
- package/dist/auth/types.js +0 -24
- package/dist/auth/types.js.map +0 -1
- package/dist/donation/donation-service.d.ts +0 -389
- package/dist/donation/donation-service.js +0 -828
- package/dist/donation/donation-service.js.map +0 -1
- package/dist/donation/donation-store.d.ts +0 -51
- package/dist/donation/donation-store.js +0 -152
- package/dist/donation/donation-store.js.map +0 -1
- package/dist/donation/donation-supervisor.js +0 -364
- package/dist/donation/donation-supervisor.js.map +0 -1
- package/dist/donation/grant-service.d.ts +0 -80
- package/dist/donation/grant-service.js +0 -210
- package/dist/donation/grant-service.js.map +0 -1
- package/dist/donation/grant-store.d.ts +0 -38
- package/dist/donation/grant-store.js +0 -135
- package/dist/donation/grant-store.js.map +0 -1
- package/dist/donation/index.d.ts +0 -20
- package/dist/donation/index.js +0 -17
- package/dist/donation/index.js.map +0 -1
- package/dist/donation/types.d.ts +0 -224
- package/dist/donation/types.js +0 -40
- package/dist/donation/types.js.map +0 -1
- package/dist/installer/identity.js.map +0 -1
- package/dist/owner/index.d.ts +0 -11
- package/dist/owner/index.js +0 -11
- package/dist/owner/index.js.map +0 -1
- package/dist/owner/owner-node-client.d.ts +0 -110
- package/dist/owner/owner-node-client.js +0 -184
- package/dist/owner/owner-node-client.js.map +0 -1
- package/dist/server/routes/bootstrap-node-validation.d.ts +0 -115
- package/dist/server/routes/bootstrap-node-validation.js +0 -197
- package/dist/server/routes/bootstrap-node-validation.js.map +0 -1
- package/dist/server/routes/grants-admin.d.ts +0 -29
- package/dist/server/routes/grants-admin.js +0 -58
- package/dist/server/routes/grants-admin.js.map +0 -1
- package/dist/server/routes/grants.d.ts +0 -28
- package/dist/server/routes/grants.js +0 -165
- package/dist/server/routes/grants.js.map +0 -1
- package/dist/server/routes/provision-request-validation.d.ts +0 -45
- package/dist/server/routes/provision-request-validation.js +0 -97
- package/dist/server/routes/provision-request-validation.js.map +0 -1
- package/dist/server/routes/strands.d.ts +0 -20
- package/dist/server/routes/strands.js +0 -38
- package/dist/server/routes/strands.js.map +0 -1
- package/dist/server/routes/trust-circle.d.ts +0 -17
- package/dist/server/routes/trust-circle.js +0 -35
- package/dist/server/routes/trust-circle.js.map +0 -1
- package/dist/strands/index.d.ts +0 -7
- package/dist/strands/index.js +0 -6
- package/dist/strands/index.js.map +0 -1
- package/dist/strands/strand-service.d.ts +0 -50
- package/dist/strands/strand-service.js +0 -103
- package/dist/strands/strand-service.js.map +0 -1
- package/dist/strands/types.d.ts +0 -93
- package/dist/strands/types.js +0 -23
- package/dist/strands/types.js.map +0 -1
- package/dist/ui/assets/index-C6nELNfC.js +0 -23
- package/dist/ui/assets/index-C6nELNfC.js.map +0 -1
- package/dist/ui/assets/index-TtIYSeZO.css +0 -1
- package/src/__tests__/cli-invite.smoke.test.ts +0 -192
- package/src/__tests__/host-owner.smoke.test.ts +0 -123
- package/src/__tests__/orchestrator-owner.test.ts +0 -234
- package/src/__tests__/orchestrator-pin-keys.test.ts +0 -152
- package/src/auth/__tests__/duration.test.ts +0 -28
- package/src/auth/__tests__/self-label.test.ts +0 -85
- package/src/auth/__tests__/trust-circle-integration.test.ts +0 -152
- package/src/auth/__tests__/trust-circle-store.test.ts +0 -115
- package/src/auth/__tests__/trust-circle.test.ts +0 -445
- package/src/auth/duration.ts +0 -33
- package/src/auth/index.ts +0 -21
- package/src/auth/self-label.ts +0 -74
- package/src/auth/trust-circle-store.ts +0 -155
- package/src/auth/trust-circle.ts +0 -395
- package/src/auth/types.ts +0 -99
- package/src/donation/__tests__/donation-service.test.ts +0 -1193
- package/src/donation/__tests__/donation-supervisor.test.ts +0 -548
- package/src/donation/__tests__/grant-service.test.ts +0 -213
- package/src/donation/__tests__/grant-store.test.ts +0 -113
- package/src/donation/donation-service.ts +0 -1033
- package/src/donation/donation-store.ts +0 -176
- package/src/donation/donation-supervisor.ts +0 -411
- package/src/donation/grant-service.ts +0 -252
- package/src/donation/grant-store.ts +0 -152
- package/src/donation/index.ts +0 -65
- package/src/donation/types.ts +0 -260
- package/src/owner/__tests__/owner-node-client.test.ts +0 -194
- package/src/owner/index.ts +0 -12
- package/src/owner/owner-node-client.ts +0 -259
- package/src/server/__tests__/bootstrap-node-validation.test.ts +0 -138
- package/src/server/__tests__/grants-admin-route.test.ts +0 -171
- package/src/server/__tests__/grants-route.test.ts +0 -394
- package/src/server/__tests__/strands-route.test.ts +0 -234
- package/src/server/routes/bootstrap-node-validation.ts +0 -206
- package/src/server/routes/grants-admin.ts +0 -74
- package/src/server/routes/grants.ts +0 -193
- package/src/server/routes/provision-request-validation.ts +0 -105
- package/src/server/routes/strands.ts +0 -54
- package/src/server/routes/trust-circle.ts +0 -49
- package/src/strands/__tests__/strand-service.test.ts +0 -165
- package/src/strands/index.ts +0 -14
- package/src/strands/strand-service.ts +0 -135
- package/src/strands/types.ts +0 -102
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
|
|
3
|
+
import type { ManagedNodeInfo } from '../orchestrator/types.js';
|
|
4
|
+
|
|
5
|
+
const log = debug('cadre:host:nat-address-watch');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The shortest gap between two address restarts of one node. Bounds a flapping
|
|
9
|
+
* router (a mapping that keeps failing and coming back) to one restart per node
|
|
10
|
+
* per window; a difference found inside the window waits for the first check
|
|
11
|
+
* after it ends.
|
|
12
|
+
*/
|
|
13
|
+
export const NAT_ADDRESS_RESTART_MIN_INTERVAL_MS = 10 * 60_000;
|
|
14
|
+
|
|
15
|
+
/** Asked to restart one node so it starts announcing its current public addresses. */
|
|
16
|
+
export type NodeAddressesStaleListener = (nodeId: string) => void | Promise<void>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Notices a running node whose announced public addresses differ from the ones
|
|
20
|
+
* it should announce now, and asks its listeners to restart that node. A node
|
|
21
|
+
* learns its public addresses only at start (`CADRE_APPEND_ANNOUNCE_ADDRS`), so
|
|
22
|
+
* a restart is how a changed mapping, forward, DDNS hostname or external IP
|
|
23
|
+
* reaches it.
|
|
24
|
+
*/
|
|
25
|
+
export class AddressWatch {
|
|
26
|
+
private readonly listeners = new Set<NodeAddressesStaleListener>();
|
|
27
|
+
/** When each node was last asked to restart (ms since epoch). */
|
|
28
|
+
private readonly lastRestartAt = new Map<string, number>();
|
|
29
|
+
|
|
30
|
+
constructor(private readonly now: () => number) {}
|
|
31
|
+
|
|
32
|
+
/** Register a restart listener. Returns an unsubscribe fn. */
|
|
33
|
+
subscribe(listener: NodeAddressesStaleListener): () => void {
|
|
34
|
+
this.listeners.add(listener);
|
|
35
|
+
return () => { this.listeners.delete(listener); };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Compare every running node's announced addresses with `expected(node)`, as
|
|
40
|
+
* sets, and ask for a restart of each that differs and was not restarted
|
|
41
|
+
* within {@link NAT_ADDRESS_RESTART_MIN_INTERVAL_MS}.
|
|
42
|
+
*/
|
|
43
|
+
check(nodes: ManagedNodeInfo[], expected: (node: ManagedNodeInfo) => string[]): void {
|
|
44
|
+
this.forgetMissing(nodes);
|
|
45
|
+
if (this.listeners.size === 0) return;
|
|
46
|
+
for (const node of nodes) {
|
|
47
|
+
if (node.status !== 'running') continue;
|
|
48
|
+
if (sameAddressSet(node.announcedAddrs, expected(node))) continue;
|
|
49
|
+
if (this.restartedRecently(node.id)) {
|
|
50
|
+
log('node %s announces stale addresses; restart deferred by the rate limit', node.id);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
this.lastRestartAt.set(node.id, this.now());
|
|
54
|
+
log('node %s announces stale addresses; asking for a restart', node.id);
|
|
55
|
+
this.notify(node.id);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** A terminated node's id may come back as a fresh node, which owes nothing to the old window. */
|
|
60
|
+
private forgetMissing(nodes: ManagedNodeInfo[]): void {
|
|
61
|
+
const listed = new Set(nodes.map((n) => n.id));
|
|
62
|
+
for (const id of this.lastRestartAt.keys()) {
|
|
63
|
+
if (!listed.has(id)) this.lastRestartAt.delete(id);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private restartedRecently(nodeId: string): boolean {
|
|
68
|
+
const last = this.lastRestartAt.get(nodeId);
|
|
69
|
+
return last !== undefined && this.now() - last < NAT_ADDRESS_RESTART_MIN_INTERVAL_MS;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Fire-and-forget: a restart takes seconds and must not hold up the NAT pass that found it. */
|
|
73
|
+
private notify(nodeId: string): void {
|
|
74
|
+
for (const listener of this.listeners) {
|
|
75
|
+
try {
|
|
76
|
+
void Promise.resolve(listener(nodeId)).catch((err: unknown) => { logRestartFailure(nodeId, err); });
|
|
77
|
+
} catch (err) {
|
|
78
|
+
logRestartFailure(nodeId, err);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function sameAddressSet(a: readonly string[], b: readonly string[]): boolean {
|
|
85
|
+
const left = new Set(a);
|
|
86
|
+
const right = new Set(b);
|
|
87
|
+
return left.size === right.size && [...left].every((addr) => right.has(addr));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function logRestartFailure(nodeId: string, err: unknown): void {
|
|
91
|
+
log('address restart of node %s failed: %s', nodeId, err instanceof Error ? err.message : String(err));
|
|
92
|
+
}
|
package/src/nat/ddns/duckdns.ts
CHANGED
|
@@ -13,7 +13,8 @@ const log = debug('cadre:host:nat-ddns:duckdns');
|
|
|
13
13
|
* Response is plain text — `OK` on success, `KO` on failure.
|
|
14
14
|
*
|
|
15
15
|
* `hostname` may be supplied as the bare subdomain (`foo`) or the FQDN
|
|
16
|
-
* (`foo.duckdns.org`);
|
|
16
|
+
* (`foo.duckdns.org`); the update strips the suffix, and `qualifyHostname`
|
|
17
|
+
* adds it.
|
|
17
18
|
*/
|
|
18
19
|
export const duckDnsProvider: DdnsProvider = {
|
|
19
20
|
id: 'duckdns',
|
|
@@ -21,6 +22,9 @@ export const duckDnsProvider: DdnsProvider = {
|
|
|
21
22
|
configFields: [
|
|
22
23
|
{ key: 'token', label: 'DuckDNS token', secret: true },
|
|
23
24
|
],
|
|
25
|
+
qualifyHostname(hostname: string): string {
|
|
26
|
+
return `${stripSuffix(hostname)}${SUFFIX}`;
|
|
27
|
+
},
|
|
24
28
|
async update(
|
|
25
29
|
config: Record<string, string>,
|
|
26
30
|
hostname: string,
|
package/src/nat/ddns/index.ts
CHANGED
|
@@ -19,6 +19,12 @@ export interface DdnsProvider {
|
|
|
19
19
|
readonly id: string;
|
|
20
20
|
readonly displayName: string;
|
|
21
21
|
readonly configFields: ReadonlyArray<DdnsConfigField>;
|
|
22
|
+
/**
|
|
23
|
+
* The fully qualified name the provider publishes for a hostname as the user
|
|
24
|
+
* typed it. Stored in place of the typed form because hosted nodes announce the
|
|
25
|
+
* stored hostname as `/dns4/<hostname>`, so it has to resolve on its own.
|
|
26
|
+
*/
|
|
27
|
+
qualifyHostname(hostname: string): string;
|
|
22
28
|
/** Push `ip` for `hostname`. Throws NatError(ddns_update_failed) on failure. */
|
|
23
29
|
update(
|
|
24
30
|
config: Record<string, string>,
|
package/src/nat/index.ts
CHANGED
|
@@ -2,24 +2,42 @@
|
|
|
2
2
|
* NAT / DDNS substrate for cadre-host.
|
|
3
3
|
*
|
|
4
4
|
* See ./nat-service.ts for the top-level orchestrator and `docs/cadre-host.md`
|
|
5
|
-
* for integration notes (the long-running process owner is `cadre-host
|
|
5
|
+
* for integration notes (the long-running process owner is `cadre-host start`).
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
export {
|
|
9
|
-
|
|
8
|
+
export {
|
|
9
|
+
NatService,
|
|
10
|
+
createNatHandlers,
|
|
11
|
+
NAT_UNMAP_GRACE_MS,
|
|
12
|
+
NAT_RECONCILE_INTERVAL_MS,
|
|
13
|
+
NAT_IP_REDETECT_INTERVAL_MS,
|
|
14
|
+
} from './nat-service.js';
|
|
15
|
+
export type { NatServiceOptions, NatNodeSource, NatChangeListener } from './nat-service.js';
|
|
16
|
+
export { NAT_ADDRESS_RESTART_MIN_INTERVAL_MS } from './address-watch.js';
|
|
17
|
+
export type { NodeAddressesStaleListener } from './address-watch.js';
|
|
10
18
|
export { NatStore } from './nat-store.js';
|
|
11
19
|
export {
|
|
12
20
|
NatError,
|
|
13
21
|
} from './types.js';
|
|
14
22
|
export type {
|
|
15
23
|
NatStatusSnapshot,
|
|
24
|
+
NatGatewayStatus,
|
|
16
25
|
NatDdnsStatus,
|
|
26
|
+
NatNetworkStatus,
|
|
27
|
+
NetworkMode,
|
|
28
|
+
NetworkSetting,
|
|
17
29
|
NatSettingsFile,
|
|
18
30
|
NatDdnsSettings,
|
|
19
31
|
NatHandlers,
|
|
20
32
|
NatErrorCode,
|
|
21
|
-
PortForwardMode,
|
|
22
33
|
DirectReachability,
|
|
34
|
+
NodeReachability,
|
|
35
|
+
NodeVerdict,
|
|
36
|
+
PortKind,
|
|
37
|
+
PortRoute,
|
|
38
|
+
PortRouteSource,
|
|
39
|
+
ManualForward,
|
|
40
|
+
ManualForwardPatch,
|
|
23
41
|
DdnsProviderInfo,
|
|
24
42
|
DdnsConfigField,
|
|
25
43
|
} from './types.js';
|
|
@@ -33,21 +51,23 @@ export type {
|
|
|
33
51
|
ExternalIpDetectorOptions,
|
|
34
52
|
} from './external-ip.js';
|
|
35
53
|
export {
|
|
36
|
-
|
|
37
|
-
|
|
54
|
+
UpnpPortMapper,
|
|
55
|
+
pickLanAddress,
|
|
38
56
|
DEFAULT_LEASE_TTL_MS,
|
|
39
57
|
DEFAULT_REFRESH_MS,
|
|
58
|
+
GATEWAY_DISCOVERY_TIMEOUT_MS,
|
|
40
59
|
} from './port-mapper.js';
|
|
41
60
|
export type {
|
|
42
61
|
PortMapper,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
PortMapperServiceOptions,
|
|
62
|
+
GatewayInfo,
|
|
63
|
+
PortMapRequest,
|
|
64
|
+
PortMapResult,
|
|
47
65
|
} from './port-mapper.js';
|
|
48
|
-
export {
|
|
49
|
-
export {
|
|
50
|
-
export
|
|
66
|
+
export { evaluateNodeReachability, evaluateHostReachability } from './reachability.js';
|
|
67
|
+
export type { NodeVerdictInput, NodeVerdictResult } from './reachability.js';
|
|
68
|
+
export { buildPublicAddresses, isPublicIpv4 } from './address-resolver.js';
|
|
69
|
+
export { publicInterfaceAddress, effectiveNetworkMode } from './network-mode.js';
|
|
70
|
+
export type { PublicAddressInput } from './address-resolver.js';
|
|
51
71
|
export {
|
|
52
72
|
BUILTIN_PROVIDERS,
|
|
53
73
|
getProvider,
|