@push.rocks/smartdns 7.12.1 → 8.0.1

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.
@@ -83,11 +83,14 @@ export class RustDnsBridge extends plugins.events.EventEmitter {
83
83
  }
84
84
  /**
85
85
  * Process a raw DNS packet via IPC (for manual/passthrough mode).
86
- * Returns the DNS response as a Buffer.
86
+ * Returns the DNS response as a Buffer. Pass `transport: 'udp'` when the
87
+ * response will be sent as a UDP datagram, so it is truncated (TC bit) to
88
+ * the client's advertised payload size instead of exceeding it.
87
89
  */
88
- async processPacket(packet) {
90
+ async processPacket(packet, transport) {
89
91
  const result = await this.bridge.sendCommand('processPacket', {
90
92
  packet: packet.toString('base64'),
93
+ transport,
91
94
  });
92
95
  return Buffer.from(result.packet, 'base64');
93
96
  }
@@ -134,4 +137,4 @@ function getPlatformSuffix() {
134
137
  }
135
138
  return null;
136
139
  }
137
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5ydXN0ZG5zYnJpZGdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfc2VydmVyL2NsYXNzZXMucnVzdGRuc2JyaWRnZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQStFeEM7O0dBRUc7QUFDSCxNQUFNLE9BQU8sYUFBYyxTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWTtJQUc1RDtRQUNFLEtBQUssRUFBRSxDQUFDO1FBRVIsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQ3JDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQ3ZELElBQUksQ0FDTCxDQUFDO1FBRUYsMkVBQTJFO1FBQzNFLE1BQU0sY0FBYyxHQUFHLGlCQUFpQixFQUFFLENBQUM7UUFDM0MsTUFBTSxVQUFVLEdBQWEsRUFBRSxDQUFDO1FBRWhDLDBFQUEwRTtRQUMxRSxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ25CLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFdBQVcsRUFBRSxXQUFXLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzRixDQUFDO1FBQ0QsMkNBQTJDO1FBQzNDLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFdBQVcsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ3ZFLHdCQUF3QjtRQUN4QixVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO1FB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
140
+ //# 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": "7.12.1",
3
+ "version": "8.0.1",
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": {
package/readme.hints.md CHANGED
@@ -143,9 +143,129 @@ The test suite demonstrates:
143
143
  - Properly serializes both components for DNSSEC signature generation
144
144
  - Enables mail exchange records to be authenticated with DNSSEC
145
145
 
146
+ ## Authority Model (server)
147
+
148
+ Authority comes from **configuration**, never from the presence of a handler.
149
+
150
+ - `authoritativeZones` (falling back to `[dnssecZone]`) is the single source of
151
+ truth for the `aa` bit. An answer only carries `aa` when the queried name
152
+ falls inside one of those zones.
153
+ - `registerHandler(pattern, types, handler, options?)` takes
154
+ `options.authority`:
155
+ - `'authoritative'` (default) — the handler only contributes for names inside
156
+ a configured zone. A match outside every zone is **suppressed**, not
157
+ answered, and reported on the `refused` event. A registration that cannot
158
+ match any configured zone also logs a warning once, at registration time.
159
+ - `'non-authoritative'` — the handler may answer any matching name, but the
160
+ response never carries `aa` and is never DNSSEC-signed. This is the mode
161
+ for split-horizon / private-route overlays.
162
+ - `aa` is a per-message flag, so a single non-authoritative contribution
163
+ downgrades the whole response.
164
+
165
+ Why this matters: before v8, registering a handler *was* the public claim of
166
+ authority. A private-route overlay registered for a domain delegated elsewhere
167
+ made the public nameserver answer with `aa` and an RFC1918 address, while
168
+ refusing every other query type for the same name. Both halves came from the
169
+ same defect — two disagreeing sources of truth.
170
+
171
+ ### Response outcomes
172
+
173
+ `TDnsQueryResponseKind` maps one-to-one onto the wire:
174
+
175
+ | kind | rcode | `aa` | authority section |
176
+ | --- | --- | --- | --- |
177
+ | `answer` | 0 | yes | — |
178
+ | `nonAuthoritativeAnswer` | 0 | no | — |
179
+ | `authoritativeNegative` (NODATA) | 0 | yes | zone SOA |
180
+ | `authoritativeNameError` (NXDOMAIN) | 3 | yes | zone SOA |
181
+ | `refused` | 5 | no | — |
182
+ | `servfail` | 2 | no | — |
183
+
184
+ NXDOMAIN is only emitted when the name provably does not exist: no handler
185
+ pattern matches it for any type, it is not the apex of a configured zone, no
186
+ configured zone sits below it, and no handler pattern is anchored strictly
187
+ below it (literal `.name` suffix, or a wildcard that matches a probe label —
188
+ mid-label wildcards such as `x.*.example.com` are not fully inverted by this
189
+ check and can still leave an ancestor at NXDOMAIN). The apex always exists
190
+ (it answers its own SOA), and a name with covered descendants is an empty
191
+ non-terminal — both get NODATA, because NXDOMAIN denies the entire subtree
192
+ (RFC 8020) and a wrong one lets aggressive negative caching darken the zone.
193
+ A catch-all pattern such as `'*'` therefore suppresses NXDOMAIN entirely —
194
+ that is deliberate.
195
+
196
+ The zone apex answers its own SOA even with no registered SOA handler; an
197
+ authoritative server that cannot answer SOA for its own zone breaks negative
198
+ caching and resolver heuristics.
199
+
200
+ One deliberate exception to the table: RFC 6761 localhost handling (when
201
+ `enableLocalhostHandling` is on) answers `localhost` A/AAAA with `aa` set even
202
+ though `localhost` is outside every configured zone — special-use names are
203
+ authoritative by definition, not by delegation.
204
+
205
+ ## Handler Lifecycle
206
+
207
+ - `registerHandler` returns an `IDnsHandlerRegistration` with a unique `id` and
208
+ an `unregister()` that removes **only** that registration.
209
+ - `unregisterHandlerById(id)` and `unregisterHandlersByOwner(owner)` are the
210
+ precise teardown primitives; `listHandlers()` exposes the current set for
211
+ leak checks.
212
+ - `unregisterHandler(pattern, types)` is retained and unchanged: it still
213
+ removes *every* handler matching that pattern/type pair. It cannot distinguish
214
+ two consumers sharing a key — prefer the handle.
215
+ - ACME authorization follows the same rule: `filterAuthorizedDomains` /
216
+ `retrieveSslCertificate` admit exactly the domains inside a configured
217
+ authoritative zone. Handler registrations play no part — a DNS-01 challenge
218
+ for an out-of-zone domain could never validate, because its challenge TXT
219
+ handler would be suppressed.
220
+
221
+ ## Transport And Protocol Notes
222
+
223
+ - **EDNS0**: a request carrying an OPT record always gets an OPT back
224
+ (RFC 6891 6.1.1), advertising `DNS_ADVERTISED_UDP_PAYLOAD` (1232). Requests
225
+ without OPT get no OPT. Client-advertised payload sizes are clamped up to 512
226
+ so a hostile OPT cannot force pathological truncation.
227
+ - **Truncation**: UDP responses are truncated to the client's advertised payload
228
+ size with the TC bit set, so resolvers retry over TCP. Without this, oversized
229
+ datagrams were emitted and silently dropped by real networks. Truncation is
230
+ size arithmetic, never a re-encode per dropped record — the encoder does not
231
+ compress names, so record sizes are additive (`DnsPacket::encoded_len`).
232
+ `processRawDnsPacketAsync(packet, 'udp')` declares the same UDP bound for the
233
+ manual path (`handleUdpMessage` passes it automatically); without the hint no
234
+ size bound is applied, which is correct for TCP and DoH framing. Note the
235
+ manual-path deadlock under Known Limitations before relying on this.
236
+ - **RA** is cleared on every path — this server never recurses.
237
+ - **RDATA validation** fails closed: a handler returning an unencodable value
238
+ (for example a non-IPv4 string for an A record) produces SERVFAIL and an error
239
+ log, rather than a malformed record on the wire.
240
+ - **SOA serial** is fixed for the lifetime of the server process and passed to
241
+ Rust via `soaSerial`, so apex answers and negative authorities agree.
242
+
243
+ ## Observability
244
+
245
+ - `query` events carry `responseKind`, `authorityZone` and `suppressedHandlers`.
246
+ - `refused` events fire for every refusal and every suppressed handler match,
247
+ carrying the handler `id`, `domainPattern` and `owner`. Wire this up: the
248
+ original incident was invisible for weeks because nothing surfaced it.
249
+
146
250
  ## Known Limitations
147
251
 
148
252
  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)
253
+ 2. **NXDOMAIN under catch-all patterns**: see the authority model above.
254
+ 3. **SOA serial does not track zone changes** — it is a process-lifetime
255
+ constant, not a change counter. Secondaries driven by AXFR/IXFR are not
256
+ 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.
149
269
  ## Static Rust Binaries
150
270
 
151
271
  - 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
@@ -114,7 +114,7 @@ interface ISmartDnsConstructorOptions {
114
114
 
115
115
  | Strategy | Behavior |
116
116
  |---|---|
117
- | `prefer-system` | 🏠 Try the OS resolver first, fall back to Rust DoH. Honors `/etc/hosts`. |
117
+ | `prefer-system` | 🏠 Try the Node DNS resolver first, then fall back to Rust DoH. |
118
118
  | `system` | 🏠 Use only the Node.js system resolver. No Rust binary needed. |
119
119
  | `doh` | 🌐 Use only DNS-over-HTTPS (RFC 8484 wire format via Cloudflare). Rust-powered. |
120
120
  | `udp` | ⚡ Use only raw UDP queries to upstream resolver (Cloudflare 1.1.1.1). Rust-powered. |
@@ -174,6 +174,11 @@ perform their preferred attempt first and, when enabled, at most one DoH fallbac
174
174
  a missing result or an error. The fallback result is authoritative and `attempts` retains both outcomes.
175
175
  Set `allowDohFallback: false` to prohibit that second attempt.
176
176
 
177
+ When `timeoutMs` is set, every strict `system` attempt owns an isolated Node resolver. SmartDNS
178
+ returns `DNS_QUERY_TIMEOUT` at the deadline and cancels the underlying native query, so timed-out
179
+ lookups do not continue accumulating in the background. Isolated resolvers inherit servers selected
180
+ through `makeNodeProcessUseDnsProvider()`.
181
+
177
182
  The strict `system` path uses Node's explicit DNS resolvers (`resolve4`, `resolve6`, `resolveTxt`,
178
183
  `resolveMx`, `resolveNs`, `resolveCname`, `resolvePtr`, `resolveSrv`, and `resolveSoa`). This makes
179
184
  DNS response semantics observable and intentionally differs from the legacy A/AAAA path.
@@ -263,6 +268,7 @@ interface IDnsServerOptions {
263
268
  httpsKey: string; // PEM private key (path or content)
264
269
  httpsCert: string; // PEM certificate (path or content)
265
270
  dnssecZone: string; // Zone for DNSSEC signing
271
+ authoritativeZones?: string[]; // Zones this server is authoritative for (default: [dnssecZone])
266
272
  primaryNameserver?: string; // SOA mname field (default: 'ns1.{dnssecZone}')
267
273
  udpBindInterface?: string; // IP to bind UDP (default: '0.0.0.0')
268
274
  tcpBindInterface?: string; // IP to bind TCP (defaults to udpBindInterface)
@@ -312,6 +318,8 @@ await server.start();
312
318
 
313
319
  Handlers use **glob patterns** (via `minimatch`) to match incoming query names. Multiple handlers can contribute records to the same response.
314
320
 
321
+ 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.
322
+
315
323
  ```typescript
316
324
  // Exact domain
317
325
  server.registerHandler('example.com', ['A'], handler);
@@ -331,14 +339,15 @@ server.registerHandler('db-*.internal.example.com', ['A'], (question) => {
331
339
  };
332
340
  });
333
341
 
334
- // Catch-all
342
+ // Catch-all — '*' is anchored in no configured zone, so it must be
343
+ // registered non-authoritative or its out-of-zone answers are suppressed
335
344
  server.registerHandler('*', ['A'], (question) => ({
336
345
  name: question.name,
337
346
  type: 'A',
338
347
  class: 'IN',
339
348
  ttl: 300,
340
349
  data: '127.0.0.1',
341
- }));
350
+ }), { authority: 'non-authoritative' });
342
351
 
343
352
  // Multiple record types
344
353
  server.registerHandler('example.com', ['MX'], (question) => ({
@@ -349,11 +358,21 @@ server.registerHandler('example.com', ['MX'], (question) => ({
349
358
  data: { preference: 10, exchange: 'mail.example.com' },
350
359
  }));
351
360
 
352
- // Unregister a handler
361
+ // Unregister a handler: registerHandler returns a handle identifying
362
+ // exactly that registration
363
+ const registration = server.registerHandler('example.com', ['A'], handler);
364
+ registration.unregister();
365
+
366
+ // Precise teardown also works by id or owner label, and listHandlers()
367
+ // exposes the current set
368
+ server.registerHandler('example.com', ['TXT'], handler, { owner: 'acme-module' });
369
+ server.unregisterHandlersByOwner('acme-module');
370
+
371
+ // The coarse form removes EVERY handler on the pattern/type pair
353
372
  server.unregisterHandler('example.com', ['A']);
354
373
  ```
355
374
 
356
- When no handler matches, the server automatically returns an **SOA record** for the zone.
375
+ Negative answers are authoritative only inside configured zones: a name inside an authoritative zone that provably does not exist yields **NXDOMAIN** with the zone SOA in the AUTHORITY section; a name that exists — a covered name queried for a type no handler serves, the zone apex, or an empty non-terminal with covered names beneath it — yields **NODATA** with the SOA in AUTHORITY; names outside every configured zone are answered **REFUSED**.
357
376
 
358
377
  ### DNSSEC ✅
359
378
 
@@ -389,7 +408,7 @@ Supported algorithms: **ECDSAP256SHA256** (13), **ED25519** (15), **RSASHA256**
389
408
 
390
409
  ### SOA Records
391
410
 
392
- The server auto-generates SOA records for zones when no specific handler matches. Customize the primary nameserver:
411
+ The server carries the zone SOA in the AUTHORITY section of negative answers (NXDOMAIN and NODATA), and the zone apex answers its own SOA even without a registered SOA handler. Customize the primary nameserver:
393
412
 
394
413
  ```typescript
395
414
  const server = new DnsServer({
@@ -401,13 +420,13 @@ const server = new DnsServer({
401
420
  // Generated SOA includes:
402
421
  // mname: ns1.example.com
403
422
  // rname: hostmaster.example.com
404
- // serial: Unix timestamp
423
+ // serial: captured once at server construction, stable for the process lifetime
405
424
  // refresh: 3600, retry: 600, expire: 604800, minimum: 86400
406
425
  ```
407
426
 
408
427
  ### Let's Encrypt Integration 🔒
409
428
 
410
- Built-in ACME DNS-01 challenge support for automatic SSL certificates:
429
+ 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 `dnssecZone`):
411
430
 
412
431
  ```typescript
413
432
  const server = new DnsServer({
@@ -504,6 +523,10 @@ Process individual DNS packets directly:
504
523
  ```typescript
505
524
  // Asynchronous (via Rust bridge — includes DNSSEC signing)
506
525
  const response = await server.processRawDnsPacketAsync(packetBuffer);
526
+
527
+ // When the response goes out as a UDP datagram, pass 'udp' so it is
528
+ // truncated (TC bit) to the client's advertised EDNS0 payload size
529
+ const udpResponse = await server.processRawDnsPacketAsync(packetBuffer, 'udp');
507
530
  ```
508
531
 
509
532
  Manual TCP callers must handle DNS-over-TCP's two-byte length prefix themselves and pass only the raw DNS packet payload to `processRawDnsPacketAsync()`.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartdns',
6
- version: '7.12.1',
6
+ version: '8.0.1',
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
  }