Iterative resolution is the loop that starts at a root server and follows referrals down to the authoritative one. Today you wire that loop, asking each server in turn and descending on every referral until an answer arrives.
Resolve a name by querying from the root and following referrals to the authoritative server.
Iterative resolution is the algorithm that makes DNS a distributed system. You
start knowing only the root servers, and you walk down: ask the root for
www.example.com, and it refers you to the .com servers; ask a .com server, and
it refers you to example.com’s authoritative servers; ask one of those, and it
finally answers with the address. Each step reuses the referral reader from
lesson 28 to turn a reply into the next server to ask.
The loop is simple once the pieces exist: query the current server, and if the
reply has the answer you are done, otherwise follow its referral to the next server
and repeat. Route each reply through the result status check from lesson 26 first,
so a failing RCODE (a SERVFAIL or NXDOMAIN) ends the walk with an error instead of
being mistaken for “no answer, keep descending” - the capstone leans on exactly
that. Because each server is reached through the injectable transport (a
dial(server) that yields a query function), the entire root-to-authoritative
walk runs against scripted responses with no network at all - you can test the
real resolution algorithm deterministically. Cap the steps so a broken delegation
cannot loop forever. This is the heart of the resolver; the capstone drives it end
to end.
// Resolver gains a `dial func(server string) Transport` fieldfunc (r *Resolver) resolve(name string) (string, error) {server := rootServerfor i := 0; i < maxSteps; i++ {raw, _ := r.dial(server)(BuildQuery(nextID(), name))msg, _ := ParseMessage(raw)if a := findA(msg, name); a != "" { return a, nil } // doneserver, _ = nextServer(msg) // descend}return "", errResolutionFailed // ran out of steps}