One lost query saves a nameserver's records with that type missing, and notifies a change #231

Closed
opened 2026-10-02 07:35:59 +02:00 by clawbot · 1 comment
Collaborator

A check asks each nameserver for each record type in a separate query (queryEachType in internal/resolver/iterative.go). When one of those queries gets no reply after both tries, or its reply is truncated and the TCP retry fails (retryTCP then keeps the truncated reply), the nameserver still gets status ok as long as another type answered. The records saved for it then lack that type, or hold only what fit in the truncated reply. The watcher sends a record change, and an inconsistency with the other nameservers, then a change back on the next check. README says ok means the records are current.

Example: over TCP, ns1.google.com gives 17 TXT records for google.com; its truncated UDP reply holds 7 of them, not including the SPF record. That set of 7 is what is saved when the TCP retry fails.

Found while working on #218, which makes the tests retry such an answer and does not change the resolver. Once the resolver reports a failed type, the TXT test's retry from that issue also covers a truncated reply.

Expected: a record type that got no usable reply is never saved as that type having no records, or as the part of them that fit in a truncated reply.

Definition of done

  • When a record type's query to a nameserver gets no reply after its tries, or its reply is truncated and the TCP retry fails, the resolver reports that type as failed for that nameserver, never as having no records or as the part that fit.
  • The watcher keeps that nameserver's previous values for a failed type and sends no Record Change or Inconsistency notification for it on that check, as it already keeps a nameserver's previous addresses when their lookup fails. A nameserver whose every type failed is a failed nameserver, as today.
  • README says what happens to a record type whose query fails.
  • Tests against live DNS where a failure can be caused for real, otherwise on answers or state built in the test; no stand-in resolver, no skipped test, no longer time limit.

Model: opus-5-5 (issue); opus-5-5 (definition of done)

A check asks each nameserver for each record type in a separate query (`queryEachType` in `internal/resolver/iterative.go`). When one of those queries gets no reply after both tries, or its reply is truncated and the TCP retry fails (`retryTCP` then keeps the truncated reply), the nameserver still gets status `ok` as long as another type answered. The records saved for it then lack that type, or hold only what fit in the truncated reply. The watcher sends a record change, and an inconsistency with the other nameservers, then a change back on the next check. README says `ok` means the records are current. Example: over TCP, ns1.google.com gives 17 TXT records for google.com; its truncated UDP reply holds 7 of them, not including the SPF record. That set of 7 is what is saved when the TCP retry fails. Found while working on https://git.eeqj.de/sneak/dnswatcher/issues/218, which makes the tests retry such an answer and does not change the resolver. Once the resolver reports a failed type, the TXT test's retry from that issue also covers a truncated reply. Expected: a record type that got no usable reply is never saved as that type having no records, or as the part of them that fit in a truncated reply. ## Definition of done - When a record type's query to a nameserver gets no reply after its tries, or its reply is truncated and the TCP retry fails, the resolver reports that type as failed for that nameserver, never as having no records or as the part that fit. - The watcher keeps that nameserver's previous values for a failed type and sends no Record Change or Inconsistency notification for it on that check, as it already keeps a nameserver's previous addresses when their lookup fails. A nameserver whose every type failed is a failed nameserver, as today. - README says what happens to a record type whose query fails. - Tests against live DNS where a failure can be caused for real, otherwise on answers or state built in the test; no stand-in resolver, no skipped test, no longer time limit. Model: opus-5-5 (issue); opus-5-5 (definition of done)
clawbot self-assigned this 2026-10-02 07:38:23 +02:00
clawbot added this to the 1.0 milestone 2026-10-02 07:38:23 +02:00
Author
Collaborator

Built in #234: the resolver reports a record type whose query got no usable reply as failed for that nameserver, with none of its records; the watcher keeps that type's records from the previous check and sends no Record Change or Inconsistency for it. Where the previous check did not know them either, the type is saved in the nameserver's failedTypes and not compared until it answers.

Model: opus-5-5

Built in https://git.eeqj.de/sneak/dnswatcher/pulls/234: the resolver reports a record type whose query got no usable reply as failed for that nameserver, with none of its records; the watcher keeps that type's records from the previous check and sends no Record Change or Inconsistency for it. Where the previous check did not know them either, the type is saved in the nameserver's `failedTypes` and not compared until it answers. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/dnswatcher#231