feat: implement iterative DNS resolver
Implement full iterative DNS resolution from root servers through TLD and domain nameservers using github.com/miekg/dns. - queryDNS: UDP with retry, TCP fallback on truncation, auto-fallback to recursive mode for environments with DNS interception - FindAuthoritativeNameservers: traces delegation chain from roots, walks up label hierarchy for subdomain lookups - QueryNameserver: queries all record types (A/AAAA/CNAME/MX/TXT/SRV/ CAA/NS) with proper status classification - QueryAllNameservers: discovers auth NSes then queries each - LookupNS: delegates to FindAuthoritativeNameservers - ResolveIPAddresses: queries all NSes, follows CNAMEs (depth 10), deduplicates and sorts results 31/35 tests pass. 4 NXDOMAIN tests fail due to wildcard DNS on sneak.cloud (nxdomain-surely-does-not-exist.dns.sneak.cloud resolves to datavi.be/162.55.148.94 via catch-all). NXDOMAIN detection is correct (checks rcode==NXDOMAIN) but the zone doesn't return NXDOMAIN.
This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
|
||||
"go.uber.org/fx"
|
||||
@@ -59,65 +58,5 @@ func NewFromLogger(log *slog.Logger) *Resolver {
|
||||
return &Resolver{log: log}
|
||||
}
|
||||
|
||||
// FindAuthoritativeNameservers traces the delegation chain from
|
||||
// root servers to discover all authoritative nameservers for the
|
||||
// given domain. Returns the NS hostnames (e.g. ["ns1.example.com.",
|
||||
// "ns2.example.com."]).
|
||||
func (r *Resolver) FindAuthoritativeNameservers(
|
||||
_ context.Context,
|
||||
_ string,
|
||||
) ([]string, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
// Method implementations are in iterative.go.
|
||||
|
||||
// QueryNameserver queries a specific authoritative nameserver for
|
||||
// all supported record types (A, AAAA, CNAME, MX, TXT, SRV, CAA,
|
||||
// NS) for the given hostname. Returns a NameserverResponse with
|
||||
// per-type record slices and a status indicating success or the
|
||||
// type of failure.
|
||||
func (r *Resolver) QueryNameserver(
|
||||
_ context.Context,
|
||||
_ string,
|
||||
_ string,
|
||||
) (*NameserverResponse, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
// QueryAllNameservers discovers the authoritative nameservers for
|
||||
// the hostname's parent domain, then queries each one independently.
|
||||
// Returns a map from nameserver hostname to its response.
|
||||
func (r *Resolver) QueryAllNameservers(
|
||||
_ context.Context,
|
||||
_ string,
|
||||
) (map[string]*NameserverResponse, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
// LookupNS returns the NS record set for a domain by performing
|
||||
// iterative resolution. This is used for domain (apex) monitoring.
|
||||
func (r *Resolver) LookupNS(
|
||||
_ context.Context,
|
||||
_ string,
|
||||
) ([]string, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
// LookupAllRecords performs iterative resolution to find all DNS
|
||||
// records for the given hostname, keyed by authoritative nameserver.
|
||||
func (r *Resolver) LookupAllRecords(
|
||||
_ context.Context,
|
||||
_ string,
|
||||
) (map[string]map[string][]string, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
// ResolveIPAddresses resolves a hostname to all IPv4 and IPv6
|
||||
// addresses by querying all authoritative nameservers and following
|
||||
// CNAME chains up to MaxCNAMEDepth. Returns a deduplicated list
|
||||
// of IP address strings.
|
||||
func (r *Resolver) ResolveIPAddresses(
|
||||
_ context.Context,
|
||||
_ string,
|
||||
) ([]string, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user