resolver: a reply marked recursion available from a root server's address stops the lookup (closes #300)
check / check (push) Waiting to run

dnswatcher never asks for recursion and a root server never offers it,
so a reply marked recursion available from a root server's address
came from a resolver on the network answering in its place. The first
such reply, a refusal included, now stops the lookup at once with
"this network intercepts DNS queries", naming the address, whether or
not that resolver had the name cached. queryDNS returns a refused reply
along with ErrRefused so the mark can be seen; a refusal without the
mark is handled as before. On such a network dnswatcher and its tests
fail with that error, by design, as the owner ruled on the issue.

Model: opus-5-5
This commit was merged in pull request #301.
This commit is contained in:
2026-10-16 12:26:52 +02:00
parent adc8131191
commit b23cf43abf
5 changed files with 113 additions and 9 deletions
+12
View File
@@ -561,6 +561,18 @@ This approach ensures:
- Ability to detect split-horizon or inconsistent responses across authoritative
servers.
A root server never offers recursion, so a reply marked "recursion available"
from a root server's address came from a recursive resolver on the network
answering in its place, as on a network where a router rule, a VPN or a DNS
filter sends all DNS to one resolver. The first such reply from a root server's
address, a refusal included, stops the lookup at once with the error "this
network intercepts DNS queries", naming that address, and no other root server
is asked. A lookup that every root server refuses without that mark fails with
the same error. Every lookup starts at the root servers, so on such a network
every lookup fails with that error, whether or not that resolver has the name
cached, and dnswatcher's tests fail there too. That is by design: nothing asks
again another way or otherwise works around the interception.
A watched name's records are stored as its nameservers return them, CNAME
included. When they return a CNAME and no address, the chain of every CNAME
target they gave is followed (with a depth limit to prevent loops) to the A and