feat: DNS host selection - system resolver, --dns-upstream flag, root hints

- Replace hardcoded 127.0.0.1:53 in systemResolver() with actual system
  DNS from /etc/resolv.conf (falls back to 127.0.0.1:53 if unavailable)
- Add Resolver field to RootDiscoveryConfig so callers can override the
  upstream resolver used during root server discovery
- Add --dns-upstream flag (e.g. --dns-upstream 8.8.8.8:53) to exploredns
  CLI and DNSUpstream field to Config
- Add internal/dns/hints.go with all 13 IANA root server IPv4/IPv6
  addresses as embedded constants (RootHints []RootServer)
- Update tests: fix real_exchange_test.go call site; add hints_test.go
  covering RootHints correctness and resolver helper functions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
Gary Hansen
2026-06-08 13:10:22 +10:00
co-authored by Copilot multica-agent
parent 93959c9f11
commit 87898d5eb3
6 changed files with 290 additions and 31 deletions
+6
View File
@@ -21,6 +21,7 @@ func main() {
allRootServers := flag.Bool("all-root-servers", cfg.AllRootServers, "Use all 13 root servers")
rootAAAA := flag.Bool("root-aaaa", cfg.RootAAAA, "Include IPv6 root addresses")
followAAAA := flag.Bool("follow-aaaa", cfg.FollowAAAA, "Only follow AAAA for referrals")
dnsUpstream := flag.String("dns-upstream", cfg.DNSUpstream, "Upstream resolver for root discovery (e.g. 8.8.8.8:53, default: system)")
udpSize := flag.Int("udp-size", cfg.UDPSize, "EDNS0 buffer size (512-4096)")
allowTCP := flag.Bool("allow-tcp", cfg.AllowTCP, "TCP fallback on truncation")
alwaysTCP := flag.Bool("always-tcp", cfg.AlwaysTCP, "Always use TCP")
@@ -71,6 +72,7 @@ func main() {
cfg.AllRootServers = *allRootServers
cfg.RootAAAA = *rootAAAA
cfg.FollowAAAA = *followAAAA
cfg.DNSUpstream = *dnsUpstream
cfg.UDPSize = *udpSize
cfg.AllowTCP = *allowTCP
cfg.AlwaysTCP = *alwaysTCP
@@ -157,6 +159,7 @@ func main() {
IncludeAAAA: cfg.RootAAAA,
Server: rootServerAddr,
AllRoots: cfg.AllRootServers,
Resolver: cfg.DNSUpstream,
}
traverserConfig := &traverse.TraverserConfig{
@@ -179,6 +182,9 @@ func main() {
fmt.Fprintf(os.Stderr, " Allow TCP: %v\n", cfg.AllowTCP)
fmt.Fprintf(os.Stderr, " Always TCP: %v\n", cfg.AlwaysTCP)
fmt.Fprintf(os.Stderr, " Fast Mode: %v\n", cfg.Fast)
if cfg.DNSUpstream != "" {
fmt.Fprintf(os.Stderr, " DNS Upstream: %s\n", cfg.DNSUpstream)
}
}
if !cfg.Quiet && !*jsonOutput {