When an in-bailiwick nameserver cannot be resolved (no glue records and
iterative resolution fails), the traversal previously returned a generic
RespError. This made the Results section show many identical '6.7%
resulted in an error' lines and the Summary show '100% resulted in an
error' — even though the domain itself may be perfectly reachable in
practice via glue held by the registry.
Add a new RespNSResolutionFailed response type (string: ns_error)
for this specific case. Changes:
- traverse/response.go: add RespNSResolutionFailed, include it in
IsTerminal() and String()
- traverse/traverser.go: use RespNSResolutionFailed with a descriptive
ErrorMessage when ResolveNS fails in processReferral
- output/stats.go: map ns_error to nameserver lookup failed in
summaryTypeLabel
- output/text.go: handle RespNSResolutionFailed in formatResultLine
Before:
Results: 6.7% resulted in an error (x15)
Summary: 100% resulted in an error
After:
Results: 6.7% nameserver ns-a.hansenits.com.au could not be resolved (x15)
Summary: 100% nameserver lookup failed
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: multica-agent <github@multica.ai>
Add text and JSON formatters with real-time progress via traverser hooks,
summary statistics, and CLI integration for --show-* and --json flags.
Co-authored-by: multica-agent <github@multica.ai>
Add Resolver interface, BasicResolver, and CachingResolver to internal/dns.
CachingResolver wraps any Resolver with an in-memory cache keyed by
(server IP, name, type, class). Cache entries respect DNS TTL from
responses, falling back to a configurable default TTL. Thread-safe
using sync.RWMutex. Includes Len, Clear, and PurgeExpired methods
for cache management.
Closes HAN-379 (Phase 2.2).
Co-authored-by: multica-agent <github@multica.ai>
Add RootServer struct and DiscoverRoots function that queries the local
resolver for NS records of the root zone, resolves each root name to
A/AAAA addresses, and returns a list of RootServer structs.
Supports:
- Default: discovers a single root server from local resolver
- --root-server override to target a specific root server
- --all-root-servers to discover all 13 root servers
- --root-aaaa flag to include IPv6 addresses
Includes unit tests for all helper functions and integration tests
that skip gracefully when no resolver is available.
Co-authored-by: multica-agent <github@multica.ai>