@push.rocks/smartdns 8.1.0 → 8.2.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/dist_rust/rustdns-client_linux_amd64 +0 -0
- package/dist_rust/rustdns-client_linux_amd64.tsrust-build.json +14 -0
- package/dist_rust/rustdns-client_linux_arm64 +0 -0
- package/dist_rust/rustdns-client_linux_arm64.tsrust-build.json +14 -0
- package/dist_rust/rustdns_linux_amd64 +0 -0
- package/dist_rust/rustdns_linux_amd64.tsrust-build.json +14 -0
- package/dist_rust/rustdns_linux_arm64 +0 -0
- package/dist_rust/rustdns_linux_arm64.tsrust-build.json +14 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts_server/classes.dnsserver.d.ts +21 -2
- package/dist_ts_server/classes.dnsserver.js +185 -42
- package/dist_ts_server/classes.rustdnsbridge.d.ts +4 -0
- package/dist_ts_server/classes.rustdnsbridge.js +10 -1
- package/package.json +6 -6
- package/readme.hints.md +35 -19
- package/readme.md +32 -4
- package/ts/00_commitinfo_data.ts +1 -1
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "tsrust.build-provenance.v2",
|
|
3
|
+
"binarySha256": "b0419c40c34a6d5fa6d6687847f9e7cb2290348d1fc0930fe4e83c808760078a",
|
|
4
|
+
"buildInfo": {
|
|
5
|
+
"projectName": "@push.rocks/smartdns",
|
|
6
|
+
"projectVersion": "8.2.0",
|
|
7
|
+
"gitCommit": "f3f7861802c8b26d517dd454add13e1bb0909c7b",
|
|
8
|
+
"gitDirty": false,
|
|
9
|
+
"builtAt": "2026-08-22T20:55:24.742Z",
|
|
10
|
+
"tsrustVersion": "1.10.0",
|
|
11
|
+
"binary": "rustdns-client",
|
|
12
|
+
"target": "linux_amd64"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "tsrust.build-provenance.v2",
|
|
3
|
+
"binarySha256": "8b24aa046dbac269aa71e6b7b554565d5f50e5664f8f6a54c59d7fe05d232ab5",
|
|
4
|
+
"buildInfo": {
|
|
5
|
+
"projectName": "@push.rocks/smartdns",
|
|
6
|
+
"projectVersion": "8.2.0",
|
|
7
|
+
"gitCommit": "f3f7861802c8b26d517dd454add13e1bb0909c7b",
|
|
8
|
+
"gitDirty": false,
|
|
9
|
+
"builtAt": "2026-08-22T20:55:25.226Z",
|
|
10
|
+
"tsrustVersion": "1.10.0",
|
|
11
|
+
"binary": "rustdns-client",
|
|
12
|
+
"target": "linux_arm64"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "tsrust.build-provenance.v2",
|
|
3
|
+
"binarySha256": "562c4ff14d42e17d0fccd653729eea025dc4eba7be56cb4b49cd2aafe1203bb4",
|
|
4
|
+
"buildInfo": {
|
|
5
|
+
"projectName": "@push.rocks/smartdns",
|
|
6
|
+
"projectVersion": "8.2.0",
|
|
7
|
+
"gitCommit": "f3f7861802c8b26d517dd454add13e1bb0909c7b",
|
|
8
|
+
"gitDirty": false,
|
|
9
|
+
"builtAt": "2026-08-22T20:55:24.742Z",
|
|
10
|
+
"tsrustVersion": "1.10.0",
|
|
11
|
+
"binary": "rustdns",
|
|
12
|
+
"target": "linux_amd64"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "tsrust.build-provenance.v2",
|
|
3
|
+
"binarySha256": "b2d37952a49874fc35b8ee7bdd5d4c794458dd93e1f2c315425351aa111f2c49",
|
|
4
|
+
"buildInfo": {
|
|
5
|
+
"projectName": "@push.rocks/smartdns",
|
|
6
|
+
"projectVersion": "8.2.0",
|
|
7
|
+
"gitCommit": "f3f7861802c8b26d517dd454add13e1bb0909c7b",
|
|
8
|
+
"gitDirty": false,
|
|
9
|
+
"builtAt": "2026-08-22T20:55:25.226Z",
|
|
10
|
+
"tsrustVersion": "1.10.0",
|
|
11
|
+
"binary": "rustdns",
|
|
12
|
+
"target": "linux_arm64"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartdns',
|
|
6
|
-
version: '8.
|
|
6
|
+
version: '8.2.0',
|
|
7
7
|
description: 'A robust TypeScript library providing advanced DNS management and resolution capabilities including support for DNSSEC, custom DNS servers, and integration with various DNS providers.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHlMQUF5TDtDQUN2TSxDQUFBIn0=
|
|
@@ -93,7 +93,7 @@ interface LetsEncryptOptions {
|
|
|
93
93
|
export interface IDnsQueryCompletedEvent {
|
|
94
94
|
/** The original questions from the query */
|
|
95
95
|
questions: IIpcDnsQuestion[];
|
|
96
|
-
/** Whether
|
|
96
|
+
/** Whether the response contains or synthesizes an answer */
|
|
97
97
|
answered: boolean;
|
|
98
98
|
/** The outcome actually sent on the wire */
|
|
99
99
|
responseKind: TDnsQueryResponseKind;
|
|
@@ -127,6 +127,9 @@ export declare class DnsServer extends plugins.events.EventEmitter {
|
|
|
127
127
|
/** Stable for the lifetime of this server, so the apex SOA does not churn. */
|
|
128
128
|
private readonly soaSerial;
|
|
129
129
|
private bridgeSpawned;
|
|
130
|
+
private lifecycleState;
|
|
131
|
+
private lifecycleTail;
|
|
132
|
+
private pendingLifecycleOperations;
|
|
130
133
|
private httpsServer;
|
|
131
134
|
private udpServer;
|
|
132
135
|
private tcpServer;
|
|
@@ -165,14 +168,25 @@ export declare class DnsServer extends plugins.events.EventEmitter {
|
|
|
165
168
|
unregisterHandlersByOwner(owner: string): number;
|
|
166
169
|
/** Every currently registered handler, for introspection and leak checks. */
|
|
167
170
|
listHandlers(): IDnsHandlerInfo[];
|
|
171
|
+
/**
|
|
172
|
+
* Replace the authoritative zone set used by subsequent queries without
|
|
173
|
+
* restarting any listener. The input is validated and copied before the live
|
|
174
|
+
* set changes; an explicit empty array means the server claims no DNS zone.
|
|
175
|
+
*/
|
|
176
|
+
setAuthoritativeZones(authoritativeZones: string[]): void;
|
|
168
177
|
/**
|
|
169
178
|
* Start the DNS server.
|
|
170
179
|
*/
|
|
171
180
|
start(): Promise<void>;
|
|
181
|
+
private startInternal;
|
|
172
182
|
/**
|
|
173
|
-
* Stop the DNS server.
|
|
183
|
+
* Stop the DNS server and resolve only after the Rust process has closed.
|
|
174
184
|
*/
|
|
175
185
|
stop(): Promise<void>;
|
|
186
|
+
private stopInternal;
|
|
187
|
+
private enqueueLifecycle;
|
|
188
|
+
private confirmBridgeTerminationAfterFailure;
|
|
189
|
+
private clearBridgeOwnership;
|
|
176
190
|
/**
|
|
177
191
|
* Initialize servers (no-op with Rust bridge, kept for API compatibility).
|
|
178
192
|
*/
|
|
@@ -215,6 +229,8 @@ export declare class DnsServer extends plugins.events.EventEmitter {
|
|
|
215
229
|
* Filter domains to include only those the server is authoritative for.
|
|
216
230
|
*/
|
|
217
231
|
filterAuthorizedDomains(domainNames: string[]): string[];
|
|
232
|
+
private applyUpdatedCertificates;
|
|
233
|
+
private isOperational;
|
|
218
234
|
/**
|
|
219
235
|
* Resolve a DNS query event from Rust using TypeScript handlers.
|
|
220
236
|
*
|
|
@@ -227,6 +243,9 @@ export declare class DnsServer extends plugins.events.EventEmitter {
|
|
|
227
243
|
private normalizeName;
|
|
228
244
|
/** Configured authoritative zones, most specific first. */
|
|
229
245
|
private normalizedAuthoritativeZones;
|
|
246
|
+
/** Canonical set used only to detect semantically equivalent updates. */
|
|
247
|
+
private canonicalAuthoritativeZoneSet;
|
|
248
|
+
private warnIfHandlerIsOutsideAuthority;
|
|
230
249
|
/** The most specific configured zone containing `name`, if any. */
|
|
231
250
|
private zoneForName;
|
|
232
251
|
/**
|
|
@@ -3,7 +3,6 @@ import { RustDnsBridge, } from './classes.rustdnsbridge.js';
|
|
|
3
3
|
export class DnsServer extends plugins.events.EventEmitter {
|
|
4
4
|
constructor(options) {
|
|
5
5
|
super();
|
|
6
|
-
this.options = options;
|
|
7
6
|
this.handlers = [];
|
|
8
7
|
this.handlerIdCounter = 0;
|
|
9
8
|
/** Patterns already warned about, so a hot loop cannot flood the log. */
|
|
@@ -12,10 +11,19 @@ export class DnsServer extends plugins.events.EventEmitter {
|
|
|
12
11
|
this.soaSerial = Math.floor(Date.now() / 1000);
|
|
13
12
|
// Track initialization state
|
|
14
13
|
this.bridgeSpawned = false;
|
|
14
|
+
this.lifecycleState = 'stopped';
|
|
15
|
+
this.lifecycleTail = Promise.resolve();
|
|
16
|
+
this.pendingLifecycleOperations = 0;
|
|
15
17
|
// Legacy server references (kept for backward-compatible test access)
|
|
16
18
|
this.httpsServer = null;
|
|
17
19
|
this.udpServer = null;
|
|
18
20
|
this.tcpServer = null;
|
|
21
|
+
this.options = {
|
|
22
|
+
...options,
|
|
23
|
+
authoritativeZones: options.authoritativeZones === undefined
|
|
24
|
+
? undefined
|
|
25
|
+
: [...options.authoritativeZones],
|
|
26
|
+
};
|
|
19
27
|
this.bridge = new RustDnsBridge();
|
|
20
28
|
// Wire up the dnsQuery event to run TypeScript handlers
|
|
21
29
|
this.bridge.on('dnsQuery', async (event) => {
|
|
@@ -25,7 +33,7 @@ export class DnsServer extends plugins.events.EventEmitter {
|
|
|
25
33
|
const responseTimeMs = Date.now() - startTime;
|
|
26
34
|
this.emit('query', {
|
|
27
35
|
questions: event.questions,
|
|
28
|
-
answered: resolution.answers.length > 0,
|
|
36
|
+
answered: resolution.answers.length > 0 || resolution.responseKind === 'answer',
|
|
29
37
|
responseKind: resolution.responseKind,
|
|
30
38
|
authorityZone: resolution.authorityZone,
|
|
31
39
|
suppressedHandlers: resolution.suppressedHandlers,
|
|
@@ -79,16 +87,7 @@ export class DnsServer extends plugins.events.EventEmitter {
|
|
|
79
87
|
handler,
|
|
80
88
|
};
|
|
81
89
|
this.handlers.push(entry);
|
|
82
|
-
|
|
83
|
-
!this.patternCanMatchAuthoritativeZone(domainPattern) &&
|
|
84
|
-
!this.warnedOutOfZonePatterns.has(domainPattern.toLowerCase())) {
|
|
85
|
-
// Loud at the point of the mistake, rather than silently at query time.
|
|
86
|
-
this.warnedOutOfZonePatterns.add(domainPattern.toLowerCase());
|
|
87
|
-
console.warn(`smartdns: handler for '${domainPattern}' cannot match any configured authoritative zone ` +
|
|
88
|
-
`(${this.normalizedAuthoritativeZones().join(', ') || 'none'}). Its answers will be ` +
|
|
89
|
-
`suppressed. Add the zone to authoritativeZones, or register with ` +
|
|
90
|
-
`{ authority: 'non-authoritative' } if this is a deliberate overlay.`);
|
|
91
|
-
}
|
|
90
|
+
this.warnIfHandlerIsOutsideAuthority(domainPattern, authority);
|
|
92
91
|
return {
|
|
93
92
|
id,
|
|
94
93
|
domainPattern,
|
|
@@ -157,10 +156,55 @@ export class DnsServer extends plugins.events.EventEmitter {
|
|
|
157
156
|
owner: handler.owner,
|
|
158
157
|
}));
|
|
159
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Replace the authoritative zone set used by subsequent queries without
|
|
161
|
+
* restarting any listener. The input is validated and copied before the live
|
|
162
|
+
* set changes; an explicit empty array means the server claims no DNS zone.
|
|
163
|
+
*/
|
|
164
|
+
setAuthoritativeZones(authoritativeZones) {
|
|
165
|
+
if (!Array.isArray(authoritativeZones)
|
|
166
|
+
|| authoritativeZones.some((zone) => typeof zone !== 'string')) {
|
|
167
|
+
throw new TypeError('authoritativeZones must be an array of strings');
|
|
168
|
+
}
|
|
169
|
+
const currentZones = this.canonicalAuthoritativeZoneSet(this.options.authoritativeZones === undefined
|
|
170
|
+
? [this.options.dnssecZone]
|
|
171
|
+
: this.options.authoritativeZones);
|
|
172
|
+
const replacementZones = this.canonicalAuthoritativeZoneSet(authoritativeZones);
|
|
173
|
+
if (currentZones.length === replacementZones.length
|
|
174
|
+
&& currentZones.every((zone, index) => zone === replacementZones[index])) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
this.options.authoritativeZones = [...authoritativeZones];
|
|
178
|
+
const invalidAuthoritativePatterns = new Set(this.handlers
|
|
179
|
+
.filter((handler) => handler.authority === 'authoritative'
|
|
180
|
+
&& !this.patternCanMatchAuthoritativeZone(handler.domainPattern))
|
|
181
|
+
.map((handler) => handler.domainPattern.toLowerCase()));
|
|
182
|
+
for (const warnedPattern of this.warnedOutOfZonePatterns) {
|
|
183
|
+
if (!invalidAuthoritativePatterns.has(warnedPattern)) {
|
|
184
|
+
this.warnedOutOfZonePatterns.delete(warnedPattern);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
for (const handler of this.handlers) {
|
|
188
|
+
this.warnIfHandlerIsOutsideAuthority(handler.domainPattern, handler.authority);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
160
191
|
/**
|
|
161
192
|
* Start the DNS server.
|
|
162
193
|
*/
|
|
163
|
-
|
|
194
|
+
start() {
|
|
195
|
+
return this.enqueueLifecycle(() => this.startInternal());
|
|
196
|
+
}
|
|
197
|
+
async startInternal() {
|
|
198
|
+
if (this.lifecycleState === 'running') {
|
|
199
|
+
if (this.bridgeSpawned && this.bridge.running) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
await this.confirmBridgeTerminationAfterFailure(new Error('DNS server bridge exited unexpectedly'));
|
|
203
|
+
}
|
|
204
|
+
if (this.lifecycleState !== 'stopped') {
|
|
205
|
+
throw new Error(`DNS server cannot start while lifecycle state is '${this.lifecycleState}'; ` +
|
|
206
|
+
`call stop() to retry cleanup`);
|
|
207
|
+
}
|
|
164
208
|
// Validate interface addresses if provided
|
|
165
209
|
const udpInterface = this.options.udpBindInterface || '0.0.0.0';
|
|
166
210
|
const tcpInterface = this.options.tcpBindInterface || udpInterface;
|
|
@@ -175,11 +219,21 @@ export class DnsServer extends plugins.events.EventEmitter {
|
|
|
175
219
|
if (this.options.httpsBindInterface && !this.isValidIpAddress(this.options.httpsBindInterface)) {
|
|
176
220
|
throw new Error(`Invalid HTTPS bind interface: ${this.options.httpsBindInterface}`);
|
|
177
221
|
}
|
|
222
|
+
this.lifecycleState = 'starting';
|
|
178
223
|
// Spawn the Rust binary
|
|
179
224
|
if (!this.bridgeSpawned) {
|
|
180
|
-
|
|
225
|
+
let spawned;
|
|
226
|
+
try {
|
|
227
|
+
spawned = await this.bridge.spawn();
|
|
228
|
+
}
|
|
229
|
+
catch (spawnError) {
|
|
230
|
+
await this.confirmBridgeTerminationAfterFailure(spawnError);
|
|
231
|
+
throw spawnError;
|
|
232
|
+
}
|
|
181
233
|
if (!spawned) {
|
|
182
|
-
|
|
234
|
+
const spawnError = new Error('Failed to spawn rustdns binary');
|
|
235
|
+
await this.confirmBridgeTerminationAfterFailure(spawnError);
|
|
236
|
+
throw spawnError;
|
|
183
237
|
}
|
|
184
238
|
this.bridgeSpawned = true;
|
|
185
239
|
}
|
|
@@ -205,15 +259,15 @@ export class DnsServer extends plugins.events.EventEmitter {
|
|
|
205
259
|
try {
|
|
206
260
|
await this.bridge.startServer(config);
|
|
207
261
|
}
|
|
208
|
-
catch (
|
|
209
|
-
this.
|
|
210
|
-
|
|
211
|
-
throw error;
|
|
262
|
+
catch (startError) {
|
|
263
|
+
await this.confirmBridgeTerminationAfterFailure(startError);
|
|
264
|
+
throw startError;
|
|
212
265
|
}
|
|
213
266
|
// Set legacy markers for backward-compatible test checks
|
|
214
267
|
this.httpsServer = { _rustBridgeManaged: true };
|
|
215
268
|
this.udpServer = { _rustBridgeManaged: true };
|
|
216
269
|
this.tcpServer = { _rustBridgeManaged: true };
|
|
270
|
+
this.lifecycleState = 'running';
|
|
217
271
|
const udpManual = this.options.manualUdpMode || false;
|
|
218
272
|
const tcpManual = this.options.manualTcpMode || false;
|
|
219
273
|
const httpsManual = this.options.manualHttpsMode || false;
|
|
@@ -233,19 +287,60 @@ export class DnsServer extends plugins.events.EventEmitter {
|
|
|
233
287
|
}
|
|
234
288
|
}
|
|
235
289
|
/**
|
|
236
|
-
* Stop the DNS server.
|
|
290
|
+
* Stop the DNS server and resolve only after the Rust process has closed.
|
|
237
291
|
*/
|
|
238
|
-
|
|
239
|
-
|
|
292
|
+
stop() {
|
|
293
|
+
return this.enqueueLifecycle(() => this.stopInternal());
|
|
294
|
+
}
|
|
295
|
+
async stopInternal() {
|
|
296
|
+
const shouldSendStopCommand = this.bridgeSpawned && this.lifecycleState === 'running';
|
|
297
|
+
if (this.lifecycleState !== 'cleanupPending') {
|
|
298
|
+
this.lifecycleState = 'stopping';
|
|
299
|
+
}
|
|
300
|
+
let stopError;
|
|
301
|
+
if (shouldSendStopCommand) {
|
|
240
302
|
try {
|
|
241
303
|
await this.bridge.stopServer();
|
|
242
304
|
}
|
|
243
|
-
catch (
|
|
244
|
-
|
|
305
|
+
catch (error) {
|
|
306
|
+
stopError = error;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
try {
|
|
310
|
+
await this.bridge.terminate();
|
|
311
|
+
}
|
|
312
|
+
catch (terminationError) {
|
|
313
|
+
this.lifecycleState = 'cleanupPending';
|
|
314
|
+
if (stopError) {
|
|
315
|
+
throw new AggregateError([stopError, terminationError], 'Failed to stop the DNS server and terminate its Rust bridge');
|
|
245
316
|
}
|
|
246
|
-
|
|
247
|
-
this.bridgeSpawned = false;
|
|
317
|
+
throw terminationError;
|
|
248
318
|
}
|
|
319
|
+
// Once process closure is confirmed, a failed stop command is immaterial.
|
|
320
|
+
this.clearBridgeOwnership();
|
|
321
|
+
}
|
|
322
|
+
enqueueLifecycle(operationArg) {
|
|
323
|
+
this.pendingLifecycleOperations++;
|
|
324
|
+
const operation = this.lifecycleTail.then(operationArg, operationArg);
|
|
325
|
+
this.lifecycleTail = operation.then(() => undefined, () => undefined);
|
|
326
|
+
void operation.then(() => { this.pendingLifecycleOperations--; }, () => { this.pendingLifecycleOperations--; });
|
|
327
|
+
return operation;
|
|
328
|
+
}
|
|
329
|
+
async confirmBridgeTerminationAfterFailure(operationError) {
|
|
330
|
+
// A failed activation can still leave smartrust owning a child transport.
|
|
331
|
+
this.bridgeSpawned = true;
|
|
332
|
+
try {
|
|
333
|
+
await this.bridge.terminate();
|
|
334
|
+
}
|
|
335
|
+
catch (terminationError) {
|
|
336
|
+
this.lifecycleState = 'cleanupPending';
|
|
337
|
+
throw new AggregateError([operationError, terminationError], 'DNS server operation failed and Rust bridge termination was not confirmed');
|
|
338
|
+
}
|
|
339
|
+
this.clearBridgeOwnership();
|
|
340
|
+
}
|
|
341
|
+
clearBridgeOwnership() {
|
|
342
|
+
this.bridgeSpawned = false;
|
|
343
|
+
this.lifecycleState = 'stopped';
|
|
249
344
|
this.httpsServer = null;
|
|
250
345
|
this.udpServer = null;
|
|
251
346
|
this.tcpServer = null;
|
|
@@ -301,8 +396,8 @@ export class DnsServer extends plugins.events.EventEmitter {
|
|
|
301
396
|
* no size bound is applied — correct for TCP and DoH framing.
|
|
302
397
|
*/
|
|
303
398
|
async processRawDnsPacketAsync(packet, transport) {
|
|
304
|
-
if (!this.
|
|
305
|
-
throw new Error('DNS server not
|
|
399
|
+
if (!this.isOperational()) {
|
|
400
|
+
throw new Error('DNS server is not accepting packets — await start() or stop() completion');
|
|
306
401
|
}
|
|
307
402
|
return this.bridge.processPacket(packet, transport);
|
|
308
403
|
}
|
|
@@ -404,16 +499,11 @@ export class DnsServer extends plugins.events.EventEmitter {
|
|
|
404
499
|
const certificate = await client.getCertificate(order);
|
|
405
500
|
const certPath = plugins.path.join(opts.certDir, `${authorizedDomains[0]}.cert`);
|
|
406
501
|
plugins.fs.writeFileSync(certPath, certificate);
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
await this.bridge.updateCerts(privateKey, certificate);
|
|
413
|
-
}
|
|
414
|
-
catch (err) {
|
|
415
|
-
console.error('Error updating certs on Rust bridge:', err);
|
|
416
|
-
}
|
|
502
|
+
try {
|
|
503
|
+
await this.applyUpdatedCertificates(privateKey, certificate);
|
|
504
|
+
}
|
|
505
|
+
catch (err) {
|
|
506
|
+
console.error('Error updating certs on Rust bridge:', err);
|
|
417
507
|
}
|
|
418
508
|
return {
|
|
419
509
|
cert: certificate,
|
|
@@ -453,6 +543,23 @@ export class DnsServer extends plugins.events.EventEmitter {
|
|
|
453
543
|
}
|
|
454
544
|
return authorizedDomains;
|
|
455
545
|
}
|
|
546
|
+
async applyUpdatedCertificates(httpsKey, httpsCert) {
|
|
547
|
+
this.options.httpsKey = httpsKey;
|
|
548
|
+
this.options.httpsCert = httpsCert;
|
|
549
|
+
await this.enqueueLifecycle(async () => {
|
|
550
|
+
if (this.lifecycleState === 'running'
|
|
551
|
+
&& this.bridgeSpawned
|
|
552
|
+
&& this.bridge.running) {
|
|
553
|
+
await this.bridge.updateCerts(httpsKey, httpsCert);
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
isOperational() {
|
|
558
|
+
return (this.pendingLifecycleOperations === 0
|
|
559
|
+
&& this.lifecycleState === 'running'
|
|
560
|
+
&& this.bridgeSpawned
|
|
561
|
+
&& this.bridge.running);
|
|
562
|
+
}
|
|
456
563
|
// ── Private helpers ───────────────────────────────────────────────
|
|
457
564
|
/**
|
|
458
565
|
* Resolve a DNS query event from Rust using TypeScript handlers.
|
|
@@ -533,6 +640,21 @@ export class DnsServer extends plugins.events.EventEmitter {
|
|
|
533
640
|
answers.push(this.buildApexSoaAnswer(questionZone));
|
|
534
641
|
}
|
|
535
642
|
}
|
|
643
|
+
const isAuthorizedDnskeyQuery = event.dnssecRequested
|
|
644
|
+
&& event.questions.length > 0
|
|
645
|
+
&& event.questions.every((question) => question.type.toUpperCase() === 'DNSKEY'
|
|
646
|
+
&& this.normalizeName(question.name) === this.normalizeName(this.options.dnssecZone)
|
|
647
|
+
&& this.zoneForName(question.name) !== null);
|
|
648
|
+
if (isAuthorizedDnskeyQuery && authorityZone) {
|
|
649
|
+
// Rust owns the key material and synthesizes the signed RRset after this
|
|
650
|
+
// live TypeScript authority decision crosses the query callback boundary.
|
|
651
|
+
return {
|
|
652
|
+
answers: [],
|
|
653
|
+
responseKind: 'answer',
|
|
654
|
+
authorityZone,
|
|
655
|
+
suppressedHandlers,
|
|
656
|
+
};
|
|
657
|
+
}
|
|
536
658
|
if (answers.length > 0) {
|
|
537
659
|
// AA is a property of the message, so a single non-authoritative
|
|
538
660
|
// contribution downgrades the whole response.
|
|
@@ -563,13 +685,34 @@ export class DnsServer extends plugins.events.EventEmitter {
|
|
|
563
685
|
}
|
|
564
686
|
/** Configured authoritative zones, most specific first. */
|
|
565
687
|
normalizedAuthoritativeZones() {
|
|
566
|
-
return (this.options.authoritativeZones
|
|
567
|
-
? this.options.
|
|
568
|
-
:
|
|
688
|
+
return (this.options.authoritativeZones === undefined
|
|
689
|
+
? [this.options.dnssecZone]
|
|
690
|
+
: this.options.authoritativeZones)
|
|
569
691
|
.map((zone) => this.normalizeName(zone))
|
|
570
692
|
.filter(Boolean)
|
|
571
693
|
.sort((a, b) => b.length - a.length);
|
|
572
694
|
}
|
|
695
|
+
/** Canonical set used only to detect semantically equivalent updates. */
|
|
696
|
+
canonicalAuthoritativeZoneSet(authoritativeZones) {
|
|
697
|
+
return [...new Set(authoritativeZones
|
|
698
|
+
.map((zone) => this.normalizeName(zone))
|
|
699
|
+
.filter(Boolean))].sort();
|
|
700
|
+
}
|
|
701
|
+
warnIfHandlerIsOutsideAuthority(domainPattern, authority) {
|
|
702
|
+
const normalizedPattern = domainPattern.toLowerCase();
|
|
703
|
+
if (authority !== 'authoritative'
|
|
704
|
+
|| this.patternCanMatchAuthoritativeZone(domainPattern)
|
|
705
|
+
|| this.warnedOutOfZonePatterns.has(normalizedPattern)) {
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
// Loud at registration and whenever live authority changes invalidate an
|
|
709
|
+
// existing authoritative handler.
|
|
710
|
+
this.warnedOutOfZonePatterns.add(normalizedPattern);
|
|
711
|
+
console.warn(`smartdns: handler for '${domainPattern}' cannot match any configured authoritative zone ` +
|
|
712
|
+
`(${this.normalizedAuthoritativeZones().join(', ') || 'none'}). Its answers will be ` +
|
|
713
|
+
`suppressed. Add the zone to authoritativeZones, or register with ` +
|
|
714
|
+
`{ authority: 'non-authoritative' } if this is a deliberate overlay.`);
|
|
715
|
+
}
|
|
573
716
|
/** The most specific configured zone containing `name`, if any. */
|
|
574
717
|
zoneForName(name) {
|
|
575
718
|
const normalizedName = this.normalizeName(name);
|
|
@@ -657,4 +800,4 @@ export class DnsServer extends plugins.events.EventEmitter {
|
|
|
657
800
|
return this.zoneForName(domain) !== null;
|
|
658
801
|
}
|
|
659
802
|
}
|
|
660
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5kbnNzZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19zZXJ2ZXIvY2xhc3Nlcy5kbnNzZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUNMLGFBQWEsR0FNZCxNQUFNLDRCQUE0QixDQUFDO0FBdUlwQyxNQUFNLE9BQU8sU0FBVSxTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWTtJQWlCeEQsWUFBb0IsT0FBMEI7UUFDNUMsS0FBSyxFQUFFLENBQUM7UUFEVSxZQUFPLEdBQVAsT0FBTyxDQUFtQjtRQWZ0QyxhQUFRLEdBQWtCLEVBQUUsQ0FBQztRQUM3QixxQkFBZ0IsR0FBRyxDQUFDLENBQUM7UUFDN0IseUVBQXlFO1FBQ2pFLDRCQUF1QixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDcEQsOEVBQThFO1FBQzdELGNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztRQUUzRCw2QkFBNkI7UUFDckIsa0JBQWEsR0FBWSxLQUFLLENBQUM7UUFFdkMsc0VBQXNFO1FBQzlELGdCQUFXLEdBQVEsSUFBSSxDQUFDO1FBQ3hCLGNBQVMsR0FBUSxJQUFJLENBQUM7UUFDdEIsY0FBUyxHQUFRLElBQUksQ0FBQztRQUk1QixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksYUFBYSxFQUFFLENBQUM7UUFFbEMsd0RBQXdEO1FBQ3hELElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsS0FBcUIsRUFBRSxFQUFFO1lBQ3pELElBQUksQ0FBQztnQkFDSCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7Z0JBQzdCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENB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
|
|
803
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5kbnNzZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19zZXJ2ZXIvY2xhc3Nlcy5kbnNzZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUNMLGFBQWEsR0FNZCxNQUFNLDRCQUE0QixDQUFDO0FBdUlwQyxNQUFNLE9BQU8sU0FBVSxTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWTtJQXFCeEQsWUFBWSxPQUEwQjtRQUNwQyxLQUFLLEVBQUUsQ0FBQztRQW5CRixhQUFRLEdBQWtCLEVBQUUsQ0FBQztRQUM3QixxQkFBZ0IsR0FBRyxDQUFDLENBQUM7UUFDN0IseUVBQXlFO1FBQ2pFLDRCQUF1QixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDcEQsOEVBQThFO1FBQzdELGNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztRQUUzRCw2QkFBNkI7UUFDckIsa0JBQWEsR0FBWSxLQUFLLENBQUM7UUFDL0IsbUJBQWMsR0FBdUUsU0FBUyxDQUFDO1FBQy9GLGtCQUFhLEdBQWtCLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNqRCwrQkFBMEIsR0FBRyxDQUFDLENBQUM7UUFFdkMsc0VBQXNFO1FBQzlELGdCQUFXLEdBQVEsSUFBSSxDQUFDO1FBQ3hCLGNBQVMsR0FBUSxJQUFJLENBQUM7UUFDdEIsY0FBUyxHQUFRLElBQUksQ0FBQztRQUk1QixJQUFJLENBQUMsT0FBTyxHQUFHO1lBQ2IsR0FBRyxPQUFPO1lBQ1Ysa0JBQWtCLEVBQUUsT0FBTyxDQUFDLGtCQUFrQixLQUFLLFNBQVM7Z0JBQzFELENBQUMsQ0FBQyxTQUFTO2dCQUNYLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDO1NBQ3BDLENBQUM7UUFDRixJQUFJ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
|
|
@@ -130,6 +130,10 @@ export declare class RustDnsBridge extends plugins.events.EventEmitter {
|
|
|
130
130
|
* Kill the Rust process.
|
|
131
131
|
*/
|
|
132
132
|
kill(): void;
|
|
133
|
+
/**
|
|
134
|
+
* Terminate the Rust process and resolve only after closure is confirmed.
|
|
135
|
+
*/
|
|
136
|
+
terminate(): Promise<void>;
|
|
133
137
|
/**
|
|
134
138
|
* Whether the bridge is running.
|
|
135
139
|
*/
|
|
@@ -23,6 +23,9 @@ export class RustDnsBridge extends plugins.events.EventEmitter {
|
|
|
23
23
|
cliArgs: ['--management'],
|
|
24
24
|
requestTimeoutMs: 30_000,
|
|
25
25
|
readyTimeoutMs: 10_000,
|
|
26
|
+
maxPendingRequestsByMethod: {
|
|
27
|
+
processPacket: 256,
|
|
28
|
+
},
|
|
26
29
|
localPaths,
|
|
27
30
|
searchSystemPath: false,
|
|
28
31
|
});
|
|
@@ -107,6 +110,12 @@ export class RustDnsBridge extends plugins.events.EventEmitter {
|
|
|
107
110
|
kill() {
|
|
108
111
|
this.bridge.kill();
|
|
109
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Terminate the Rust process and resolve only after closure is confirmed.
|
|
115
|
+
*/
|
|
116
|
+
async terminate() {
|
|
117
|
+
await this.bridge.terminate();
|
|
118
|
+
}
|
|
110
119
|
/**
|
|
111
120
|
* Whether the bridge is running.
|
|
112
121
|
*/
|
|
@@ -137,4 +146,4 @@ function getPlatformSuffix() {
|
|
|
137
146
|
}
|
|
138
147
|
return null;
|
|
139
148
|
}
|
|
140
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
149
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5ydXN0ZG5zYnJpZGdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfc2VydmVyL2NsYXNzZXMucnVzdGRuc2JyaWRnZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQTBGeEM7O0dBRUc7QUFDSCxNQUFNLE9BQU8sYUFBYyxTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWTtJQUc1RDtRQUNFLEtBQUssRUFBRSxDQUFDO1FBRVIsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQ3JDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQ3ZELElBQUksQ0FDTCxDQUFDO1FBRUYsMkVBQTJFO1FBQzNFLE1BQU0sY0FBYyxHQUFHLGlCQUFpQixFQUFFLENBQUM7UUFDM0MsTUFBTSxVQUFVLEdBQWEsRUFBRSxDQUFDO1FBRWhDLDBFQUEwRTtRQUMxRSxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ25CLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFdBQVcsRUFBRSxXQUFXLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzRixDQUFDO1FBQ0QsMkNBQTJDO1FBQzNDLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFdBQVcsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ3ZFLHdCQUF3QjtRQUN4QixVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO1FB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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@push.rocks/smartdns",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A robust TypeScript library providing advanced DNS management and resolution capabilities including support for DNSSEC, custom DNS servers, and integration with various DNS providers.",
|
|
6
6
|
"exports": {
|
|
@@ -40,20 +40,20 @@
|
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@push.rocks/smartdelay": "^3.0.1",
|
|
42
42
|
"@push.rocks/smartenv": "^6.0.0",
|
|
43
|
-
"@push.rocks/smartpromise": "^4.2.
|
|
44
|
-
"@push.rocks/smartrust": "^1.
|
|
43
|
+
"@push.rocks/smartpromise": "^4.2.5",
|
|
44
|
+
"@push.rocks/smartrust": "^1.8.0",
|
|
45
45
|
"@tsclass/tsclass": "^9.5.1",
|
|
46
46
|
"acme-client": "^5.4.0",
|
|
47
|
-
"minimatch": "^10.2.
|
|
47
|
+
"minimatch": "^10.2.6"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@git.zone/tsbuild": "^4.4.2",
|
|
51
51
|
"@git.zone/tsrun": "^2.0.6",
|
|
52
|
-
"@git.zone/tsrust": "^1.
|
|
52
|
+
"@git.zone/tsrust": "^1.10.0",
|
|
53
53
|
"@git.zone/tstest": "^4.0.0",
|
|
54
54
|
"@types/dns-packet": "^5.6.5",
|
|
55
55
|
"@types/lodash.clonedeep": "^4.5.9",
|
|
56
|
-
"@types/node": "^26.
|
|
56
|
+
"@types/node": "^26.2.0",
|
|
57
57
|
"dns-packet": "^5.6.1"
|
|
58
58
|
},
|
|
59
59
|
"files": [
|
package/readme.hints.md
CHANGED
|
@@ -23,9 +23,9 @@ TypeScript retains handler registration, ACME orchestration, and the public API.
|
|
|
23
23
|
### IPC Flow
|
|
24
24
|
```
|
|
25
25
|
DNS Query -> Rust (UDP/HTTPS) -> Parse packet
|
|
26
|
-
-> Try local resolution (localhost
|
|
26
|
+
-> Try local resolution (localhost)
|
|
27
27
|
-> If handler needed: emit "dnsQuery" event to TypeScript
|
|
28
|
-
-> TypeScript runs minimatch handlers, sends "dnsQueryResult" back
|
|
28
|
+
-> TypeScript runs minimatch handlers and authorizes DNSKEY, sends "dnsQueryResult" back
|
|
29
29
|
-> Rust builds response, signs DNSSEC if requested, sends packet
|
|
30
30
|
```
|
|
31
31
|
|
|
@@ -147,9 +147,14 @@ The test suite demonstrates:
|
|
|
147
147
|
|
|
148
148
|
Authority comes from **configuration**, never from the presence of a handler.
|
|
149
149
|
|
|
150
|
-
- `authoritativeZones`
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
- `authoritativeZones` is the single source of truth for the `aa` bit. Omission
|
|
151
|
+
falls back to `[dnssecZone]`; an explicit empty array means no authority.
|
|
152
|
+
`setAuthoritativeZones()` validates and copies a replacement set synchronously,
|
|
153
|
+
so listeners stay up while subsequent queries see the new authority.
|
|
154
|
+
- DNSKEY queries for `dnssecZone` cross the TypeScript query callback before
|
|
155
|
+
Rust synthesizes the signed RRset. This keeps built-in DNSSEC answers inside
|
|
156
|
+
the same live authority boundary; an empty set cannot leak an authoritative
|
|
157
|
+
DNSKEY answer from the fixed Rust configuration.
|
|
153
158
|
- `registerHandler(pattern, types, handler, options?)` takes
|
|
154
159
|
`options.authority`:
|
|
155
160
|
- `'authoritative'` (default) — the handler only contributes for names inside
|
|
@@ -231,8 +236,12 @@ authoritative by definition, not by delegation.
|
|
|
231
236
|
compress names, so record sizes are additive (`DnsPacket::encoded_len`).
|
|
232
237
|
`processRawDnsPacketAsync(packet, 'udp')` declares the same UDP bound for the
|
|
233
238
|
manual path (`handleUdpMessage` passes it automatically); without the hint no
|
|
234
|
-
size bound is applied, which is correct for TCP and DoH framing.
|
|
235
|
-
|
|
239
|
+
size bound is applied, which is correct for TCP and DoH framing. Manual packet
|
|
240
|
+
work runs through a bounded task set so the management loop remains available
|
|
241
|
+
for handler callbacks and their results. The TypeScript bridge mirrors the
|
|
242
|
+
Rust task bound by admitting at most 256 pending `processPacket` requests;
|
|
243
|
+
excess requests fail before serialization with
|
|
244
|
+
`ERR_RUST_BRIDGE_REQUEST_LIMIT`, while control methods remain unbounded.
|
|
236
245
|
- **RA** is cleared on every path — this server never recurses.
|
|
237
246
|
- **RDATA validation** fails closed: a handler returning an unencodable value
|
|
238
247
|
(for example a non-IPv4 string for an A record) produces SERVFAIL and an error
|
|
@@ -247,6 +256,25 @@ authoritative by definition, not by delegation.
|
|
|
247
256
|
carrying the handler `id`, `domainPattern` and `owner`. Wire this up: the
|
|
248
257
|
original incident was invisible for weeks because nothing surfaced it.
|
|
249
258
|
|
|
259
|
+
## Server Lifecycle
|
|
260
|
+
|
|
261
|
+
- `start()` and `stop()` share a serialized lifecycle queue. Each caller keeps
|
|
262
|
+
its own operation result, and a rejection does not poison later operations.
|
|
263
|
+
- Repeated `start()` calls are idempotent at the `DnsServer` facade. Rust also
|
|
264
|
+
rejects duplicate active `start` commands, so low-level bridge callers cannot
|
|
265
|
+
replace listeners while detached HTTPS connection work still exists.
|
|
266
|
+
- `stop()` awaits confirmed Rust child closure before clearing ownership and
|
|
267
|
+
legacy server markers. A failed termination retains them so cleanup can be
|
|
268
|
+
retried safely.
|
|
269
|
+
- If an operation and confirmed cleanup both fail, both errors are preserved in
|
|
270
|
+
an `AggregateError`. A failed stop command is suppressed only after process
|
|
271
|
+
closure has been confirmed.
|
|
272
|
+
- A server may be started again after a confirmed stop; smartrust activates a
|
|
273
|
+
fresh process generation on the same bridge.
|
|
274
|
+
- Packet IPC is admitted only while no lifecycle operation is queued and the
|
|
275
|
+
facade state, ownership marker, and bridge liveness all agree. Certificate
|
|
276
|
+
updates use the same queue so they cannot race startup or shutdown.
|
|
277
|
+
|
|
250
278
|
## Known Limitations
|
|
251
279
|
|
|
252
280
|
1. **Handler Deduplication**: If the same handler is registered multiple times, it will contribute duplicate records (this may be desired behavior for some use cases)
|
|
@@ -254,18 +282,6 @@ authoritative by definition, not by delegation.
|
|
|
254
282
|
3. **SOA serial does not track zone changes** — it is a process-lifetime
|
|
255
283
|
constant, not a change counter. Secondaries driven by AXFR/IXFR are not
|
|
256
284
|
supported.
|
|
257
|
-
4. **Manual-path (`processPacket`) queries deadlock on handler resolution**
|
|
258
|
-
— pre-existing, not introduced by the v8 hardening. The IPC select loop in
|
|
259
|
-
`rust/crates/rustdns/src/management.rs` awaits `handle_request` inline, so
|
|
260
|
-
while `handle_process_packet` waits for the TypeScript `dnsQuery` callback
|
|
261
|
-
the loop can neither emit the query event nor read its result; every
|
|
262
|
-
handler-backed query through `processRawDnsPacketAsync` /
|
|
263
|
-
`handleUdpMessage` times out to SERVFAIL after 10 s. The built-in UDP, TCP
|
|
264
|
-
and DoH listeners are unaffected (they resolve outside the IPC request
|
|
265
|
-
loop). The `transport: 'udp'` truncation contract on this path is wired
|
|
266
|
-
and unit-tested but cannot be observed end-to-end until the loop spawns
|
|
267
|
-
`processPacket` handling instead of awaiting it inline. No test exercises
|
|
268
|
-
`processRawDnsPacketAsync`; fixing this needs its own release.
|
|
269
285
|
## Static Rust Binaries
|
|
270
286
|
|
|
271
287
|
- The Rust binaries in `dist_rust/` are statically linked (static-pie) via `"static": true` in the `@git.zone/tsrust` block of `.smartconfig.json` (tsrust >= 1.4.1). They run on both glibc (Debian/Ubuntu) and musl (Alpine) systems.
|
package/readme.md
CHANGED
|
@@ -270,7 +270,7 @@ interface IDnsServerOptions {
|
|
|
270
270
|
httpsKey: string; // PEM private key (path or content)
|
|
271
271
|
httpsCert: string; // PEM certificate (path or content)
|
|
272
272
|
dnssecZone: string; // Zone for DNSSEC signing
|
|
273
|
-
authoritativeZones?: string[]; //
|
|
273
|
+
authoritativeZones?: string[]; // Omitted defaults to [dnssecZone]; [] claims no zone
|
|
274
274
|
primaryNameserver?: string; // SOA mname field (default: 'ns1.{dnssecZone}')
|
|
275
275
|
udpBindInterface?: string; // IP to bind UDP (default: '0.0.0.0')
|
|
276
276
|
tcpBindInterface?: string; // IP to bind TCP (defaults to udpBindInterface)
|
|
@@ -316,12 +316,32 @@ await server.start();
|
|
|
316
316
|
// DNS Server started (UDP: 0.0.0.0:5333, TCP: 0.0.0.0:5333, HTTPS: 0.0.0.0:8443)
|
|
317
317
|
```
|
|
318
318
|
|
|
319
|
+
Calling `start()` again while this `DnsServer` is running is an idempotent
|
|
320
|
+
no-op. After a confirmed `stop()`, the same instance can be started again with
|
|
321
|
+
a fresh Rust process.
|
|
322
|
+
|
|
319
323
|
### Handler System 🎯
|
|
320
324
|
|
|
321
325
|
Handlers use **glob patterns** (via `minimatch`) to match incoming query names. Multiple handlers can contribute records to the same response.
|
|
322
326
|
|
|
323
327
|
Registering a handler does **not** make the server authoritative for the matched names. Authority comes solely from `authoritativeZones` (falling back to `dnssecZone`): list every zone you serve there, or queries for it are withheld. A default-authority handler whose match falls outside every configured zone is suppressed and reported on the `refused` event; register with `{ authority: 'non-authoritative' }` to deliberately serve out-of-zone names without the `aa` bit or DNSSEC signatures.
|
|
324
328
|
|
|
329
|
+
Replace the live authority set without restarting UDP, TCP, or HTTPS listeners:
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
server.setAuthoritativeZones(['example.com', 'example.net']);
|
|
333
|
+
server.setAuthoritativeZones([]); // explicitly claim no zone
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
The constructor copies its supplied array, and `setAuthoritativeZones()` validates
|
|
337
|
+
and copies replacements. Omitting `authoritativeZones` from the constructor
|
|
338
|
+
retains the backward-compatible `[dnssecZone]` default; passing or setting an
|
|
339
|
+
empty array does not fall back. DNSKEY answers for
|
|
340
|
+
`dnssecZone` pass through the same live authority decision, so removing the last
|
|
341
|
+
zone also removes the last DNSSEC authority claim. RFC 6761 `localhost` handling
|
|
342
|
+
is the deliberate exception: while enabled, built-in localhost A/AAAA answers
|
|
343
|
+
remain authoritative even when the configured zone set is empty.
|
|
344
|
+
|
|
325
345
|
```typescript
|
|
326
346
|
// Exact domain
|
|
327
347
|
server.registerHandler('example.com', ['A'], handler);
|
|
@@ -382,7 +402,7 @@ DNSSEC is enabled automatically when you set the `dnssecZone` option. The Rust b
|
|
|
382
402
|
|
|
383
403
|
- **Key generation** — ECDSA P-256 (algorithm 13) by default
|
|
384
404
|
- **DNSKEY / DS record** generation
|
|
385
|
-
- **RRSIG signing** for
|
|
405
|
+
- **RRSIG signing** for authoritative answers when the query requests DNSSEC
|
|
386
406
|
- **NSEC records** for authenticated denial of existence
|
|
387
407
|
|
|
388
408
|
```typescript
|
|
@@ -428,7 +448,7 @@ const server = new DnsServer({
|
|
|
428
448
|
|
|
429
449
|
### Let's Encrypt Integration 🔒
|
|
430
450
|
|
|
431
|
-
Built-in ACME DNS-01 challenge support for automatic SSL certificates. Challenge TXT handlers are registered at default authority, so DNS-01 validation only completes for domains inside `authoritativeZones
|
|
451
|
+
Built-in ACME DNS-01 challenge support for automatic SSL certificates. Challenge TXT handlers are registered at default authority, so DNS-01 validation only completes for domains inside `authoritativeZones`, or inside `dnssecZone` when `authoritativeZones` is omitted:
|
|
432
452
|
|
|
433
453
|
```typescript
|
|
434
454
|
const server = new DnsServer({
|
|
@@ -533,6 +553,12 @@ const udpResponse = await server.processRawDnsPacketAsync(packetBuffer, 'udp');
|
|
|
533
553
|
|
|
534
554
|
Manual TCP callers must handle DNS-over-TCP's two-byte length prefix themselves and pass only the raw DNS packet payload to `processRawDnsPacketAsync()`.
|
|
535
555
|
|
|
556
|
+
At most 256 `processRawDnsPacketAsync()` calls may be pending at once. Additional
|
|
557
|
+
calls reject before transport writes with a `RustBridgeRequestError` whose code
|
|
558
|
+
is `ERR_RUST_BRIDGE_REQUEST_LIMIT`; control and callback commands remain
|
|
559
|
+
available while packet work is saturated. New packet calls are also rejected
|
|
560
|
+
while `start()`, `stop()`, or a certificate update is queued or running.
|
|
561
|
+
|
|
536
562
|
#### Load Balancing Example
|
|
537
563
|
|
|
538
564
|
```typescript
|
|
@@ -560,7 +586,9 @@ for (let i = 0; i < numCPUs; i++) {
|
|
|
560
586
|
await server.stop();
|
|
561
587
|
```
|
|
562
588
|
|
|
563
|
-
|
|
589
|
+
`stop()` is serialized with `start()` and resolves only after the Rust process
|
|
590
|
+
has closed and its bound sockets are released. If confirmed termination fails,
|
|
591
|
+
the call rejects and retains ownership so a later `stop()` can retry cleanup.
|
|
564
592
|
|
|
565
593
|
---
|
|
566
594
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartdns',
|
|
6
|
-
version: '8.
|
|
6
|
+
version: '8.2.0',
|
|
7
7
|
description: 'A robust TypeScript library providing advanced DNS management and resolution capabilities including support for DNSSEC, custom DNS servers, and integration with various DNS providers.'
|
|
8
8
|
}
|