Files
dnswatcher/internal/resolver/errors.go
T
clawbot b23cf43abf
check / check (push) Waiting to run
resolver: a reply marked recursion available from a root server's address stops the lookup (closes #300)
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
2026-10-16 12:26:52 +02:00

82 lines
2.7 KiB
Go

package resolver
import "errors"
// NoAnswerError is returned when the walk to a name's nameservers
// reached a zone through a referral and none of that zone's
// nameservers, Nameservers as the referral names them, answered. Err
// says why they did not.
type NoAnswerError struct {
Nameservers []string
Err error
}
func (e *NoAnswerError) Error() string {
return e.Err.Error()
}
func (e *NoAnswerError) Unwrap() error {
return e.Err
}
// Sentinel errors returned by the resolver.
var (
// ErrNoNameservers is returned when no authoritative NS
// could be discovered for a domain.
ErrNoNameservers = errors.New(
"no authoritative nameservers found",
)
// ErrNXDomain is returned when the servers of the zone a domain
// is in answer NXDOMAIN: the domain does not exist.
ErrNXDomain = errors.New("domain does not exist")
// ErrNoNameserverAnswered is returned when every nameserver
// asked about a name timed out, failed or returned a referral,
// so whether the name has addresses is unknown.
ErrNoNameserverAnswered = errors.New("no nameserver answered")
// ErrNoNameserverAddress is returned when a nameserver is to be
// asked and no address for it was given.
ErrNoNameserverAddress = errors.New("nameserver has no address")
// ErrUnusableReply is returned when a server replied with an
// error such as SERVFAIL, or with a referral that leads no
// closer to the name asked about.
ErrUnusableReply = errors.New(
"reply is an error or a referral that leads no closer",
)
// ErrTruncated is the reason given for a reply too large for UDP
// whose retry over TCP failed.
ErrTruncated = errors.New(
"reply truncated and its retry over TCP failed",
)
// ErrIntercepted is returned when a root server's address gave a
// reply marked recursion available, a refusal included, which ends
// the lookup at once, or when every root server refused a query.
// Root servers do neither, so those replies came from something on
// the network answering in their place. On such a network
// dnswatcher fails with it, by design: nothing works around the
// interception.
ErrIntercepted = errors.New("this network intercepts DNS queries")
// ErrCNAMEDepthExceeded is returned when a CNAME chain
// exceeds MaxCNAMEDepth.
ErrCNAMEDepthExceeded = errors.New(
"CNAME chain depth exceeded",
)
// ErrLookupDepthExceeded is returned when nameserver addresses
// were not looked up because lookups were already maxLookupDepth
// deep, one inside another.
ErrLookupDepthExceeded = errors.New(
"lookups of nameserver addresses go too deep",
)
// ErrContextCanceled wraps context cancellation for the
// resolver's iterative queries.
ErrContextCanceled = errors.New("context canceled")
)