In order to catch exactly what a DNS server does for a DNS request from a client, I set up a DNS server (Bind v.9) at 129.170.213.53, sent it a request (with "dig @129.170.213.53 a www.cs.dartmouth.edu") and captured all packets that the server sent and received (with tcpdump and the "port 53" capture filter). Here is the result: Original request: -------------------[ 72.95.x.x -> 129.170.213.53 ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16884 ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;www.cs.dartmouth.edu. IN A The nameserver picks a root server (the addresses of root servers are hard-coded in Bind) and re-sends the query to it. The root server chose, 199.7.91.13, is "D" (look in https://en.wikipedia.org/wiki/Root_name_server), operated by the U. of Maryland, and running Bind, too): -------------------[ 129.170.213.53 -> 199.7.91.13 ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10223 ;; flags: ; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;www.cs.dartmouth.edu. IN A But that's not all: my nameserver _also_ sends a request for ".", that is, for the list of root servers (perhaps in case they changed): -------------------[ 129.170.213.53 -> 199.7.91.13 ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29823 ;; flags: ; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;. IN NS The root server responds. The response is "noerror", but has no answer record, but rather only authority and additional records. It means, "I don't know, but go ask those servers; they should know". This is how hierarchical delegation of DNS authority works. These servers enumerated in the response are, expectedly, those for the ".edu" domain: -------------------[ 199.7.91.13 -> 129.170.213.53 ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10223 ;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 7 ;; QUESTION SECTION: ;www.cs.dartmouth.edu. IN A ;; AUTHORITY SECTION: edu. 172800 IN NS a.edu-servers.net. edu. 172800 IN NS l.edu-servers.net. edu. 172800 IN NS f.edu-servers.net. edu. 172800 IN NS c.edu-servers.net. edu. 172800 IN NS d.edu-servers.net. edu. 172800 IN NS g.edu-servers.net. ;; ADDITIONAL SECTION: a.edu-servers.net. 172800 IN A 192.5.6.30 c.edu-servers.net. 172800 IN A 192.26.92.30 d.edu-servers.net. 172800 IN A 192.31.80.30 f.edu-servers.net. 172800 IN A 192.35.51.30 g.edu-servers.net. 172800 IN A 192.42.93.30 l.edu-servers.net. 172800 IN A 192.41.162.30 g.edu-servers.net. 172800 IN AAAA 2001:503:cc2c::2:36 The root server also responds to the second query, with the list of root servers (including self): -------------------[ 199.7.91.13 -> 129.170.213.53 ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29823 ;; flags: qr aa; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 15 ;; QUESTION SECTION: ;. IN NS ;; ANSWER SECTION: . 518400 IN NS h.root-servers.net. . 518400 IN NS i.root-servers.net. . 518400 IN NS f.root-servers.net. . 518400 IN NS g.root-servers.net. . 518400 IN NS l.root-servers.net. . 518400 IN NS d.root-servers.net. . 518400 IN NS m.root-servers.net. . 518400 IN NS j.root-servers.net. . 518400 IN NS a.root-servers.net. . 518400 IN NS e.root-servers.net. . 518400 IN NS b.root-servers.net. . 518400 IN NS k.root-servers.net. . 518400 IN NS c.root-servers.net. ;; ADDITIONAL SECTION: a.root-servers.net. 3600000 IN A 198.41.0.4 b.root-servers.net. 3600000 IN A 192.228.79.201 c.root-servers.net. 3600000 IN A 192.33.4.12 d.root-servers.net. 3600000 IN A 199.7.91.13 e.root-servers.net. 3600000 IN A 192.203.230.10 f.root-servers.net. 3600000 IN A 192.5.5.241 g.root-servers.net. 3600000 IN A 192.112.36.4 h.root-servers.net. 3600000 IN A 198.97.190.53 i.root-servers.net. 3600000 IN A 192.36.148.17 j.root-servers.net. 3600000 IN A 192.58.128.30 k.root-servers.net. 3600000 IN A 193.0.14.129 l.root-servers.net. 3600000 IN A 199.7.83.42 m.root-servers.net. 3600000 IN A 202.12.27.33 a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 b.root-servers.net. 3600000 IN AAAA 2001:500:84::b The next request from my server is to the first server for "edu". It's the same as before: "tell me the address of www.cs.dartmouth.edu": -------------------[ 129.170.213.53 -> 192.5.6.30 ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32067 ;; flags: ; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;www.cs.dartmouth.edu. IN A The server responds with "noerror" code and no answer, but more authority records, "ask these guys, they should know". Predictably, these are Dartmouth's external-facing nameservers, which have authority for "dartmouth.edu". Having NS records for them in "edu" server databases is what makes the delegation work. Note also that the third Dartmouth nameserver, dns-ext3, is located on a different network, 132.177.0.0/16, which belongs to the U. of New Hampshire. This is often done for redundancy and reliability: -------------------[ 192.5.6.30 -> 129.170.213.53 ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32067 ;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 3, ADDITIONAL: 3 ;; QUESTION SECTION: ;www.cs.dartmouth.edu. IN A ;; AUTHORITY SECTION: dartmouth.edu. 172800 IN NS dns-ext1.dartmouth.edu. dartmouth.edu. 172800 IN NS dns-ext2.dartmouth.edu. dartmouth.edu. 172800 IN NS dns-ext3.dartmouth.edu. ;; ADDITIONAL SECTION: dns-ext1.dartmouth.edu. 172800 IN A 129.170.170.2 dns-ext2.dartmouth.edu. 172800 IN A 129.170.170.10 dns-ext3.dartmouth.edu. 172800 IN A 132.177.102.11 Now my server asks one of these servers: -------------------[ 129.170.213.53 -> 129.170.170.10 ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11964 ;; flags: ; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;www.cs.dartmouth.edu. IN A ...and gets a response. Note that the responding server, dns-ext2.dartmouth.edu, sets the "aa" flag, indicating that this is an authoritative answer. This is a bit surprising, because we expect the CS nameserver to have authority over cs.dartmouth.edu, i.e., to hold the configuration files (a.k.a. "zone files") for the domain cs.dartmouth.edu, not the main college nameserver. Otherwise, delegation to CS would break and CS would not be able to easily bring in new names by themselves without telling dartmouth.edu servers that these names have been added. But see below. The answer is two-fold: that the real name of www.cs is katahdin.cs, and the IP address of katahdin, likely cached from previous requests this server has seen. Note that there's no authority record: -------------------[ 129.170.170.10 -> 129.170.213.53 ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11964 ;; flags: qr aa; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;www.cs.dartmouth.edu. IN A ;; ANSWER SECTION: www.cs.dartmouth.edu. 43200 IN CNAME katahdin.cs.dartmouth.edu. katahdin.cs.dartmouth.edu. 86400 IN A 129.170.213.101 My server, however, is not content with that. It goes to find the address of katahdin for itself, using another one of Dartmouth's nameservers, the one at UNH. Perhaps my server agrees with the concern above, and wants to see some authority record in the response: -------------------[ 129.170.213.53 -> 132.177.102.11 ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19815 ;; flags: ; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;katahdin.cs.dartmouth.edu. IN A UNH's server responds, and this time we get an authority record for CS (and no answer record, so this is "go ask those guys again"): -------------------[ 132.177.102.11 -> 129.170.213.53 ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19815 ;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 7, ADDITIONAL: 7 ;; QUESTION SECTION: ;katahdin.cs.dartmouth.edu. IN A ;; AUTHORITY SECTION: cs.dartmouth.edu. 28800 IN NS nickwaket2.cs.dartmouth.edu. cs.dartmouth.edu. 28800 IN NS mansfield.cs.dartmouth.edu. cs.dartmouth.edu. 28800 IN NS dns-ext2.dartmouth.edu. cs.dartmouth.edu. 28800 IN NS dns-ext1.dartmouth.edu. cs.dartmouth.edu. 28800 IN NS cs.dartmouth.edu. cs.dartmouth.edu. 28800 IN NS mansfield2.cs.dartmouth.edu. cs.dartmouth.edu. 28800 IN NS aeolus.cs.dartmouth.edu. ;; ADDITIONAL SECTION: mansfield.cs.dartmouth.edu. 28800 IN A 129.170.192.44 aeolus.cs.dartmouth.edu. 28800 IN A 129.170.213.128 dns-ext2.dartmouth.edu. 28800 IN A 129.170.170.10 cs.dartmouth.edu. 28800 IN A 129.170.212.26 dns-ext1.dartmouth.edu. 28800 IN A 129.170.170.2 mansfield2.cs.dartmouth.edu. 28800 IN A 129.170.212.67 nickwaket2.cs.dartmouth.edu. 28800 IN A 129.170.210.10 Ah, this is better, thinks my server, and queries one of these authoritative servers for CS: -------------------[ 129.170.213.53 -> 129.170.213.128 ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29341 ;; flags: ; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;katahdin.cs.dartmouth.edu. IN A And finally gets a response: -------------------[ 129.170.213.128 -> 129.170.213.53 ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29341 ;; flags: qr aa ra; QUERY: 1, ANSWER: 1, AUTHORITY: 9, ADDITIONAL: 7 ;; QUESTION SECTION: ;katahdin.cs.dartmouth.edu. IN A ;; ANSWER SECTION: katahdin.cs.Dartmouth.EDU. 86400 IN A 129.170.213.101 ;; AUTHORITY SECTION: cs.Dartmouth.EDU. 86400 IN NS aeolus.CS.Dartmouth.EDU. cs.Dartmouth.EDU. 86400 IN NS ns1.dartmouth.edu. cs.Dartmouth.EDU. 86400 IN NS mansfield2.CS.Dartmouth.EDU. cs.Dartmouth.EDU. 86400 IN NS CS.Dartmouth.EDU. cs.Dartmouth.EDU. 86400 IN NS ns2.Dartmouth.Edu. cs.Dartmouth.EDU. 86400 IN NS nickwaket2.CS.Dartmouth.EDU. cs.Dartmouth.EDU. 86400 IN NS dns-ext2.dartmouth.edu. cs.Dartmouth.EDU. 86400 IN NS mansfield.CS.Dartmouth.EDU. cs.Dartmouth.EDU. 86400 IN NS dns-ext1.dartmouth.edu. ;; ADDITIONAL SECTION: cs.Dartmouth.EDU. 86400 IN A 129.170.212.26 mansfield.cs.Dartmouth.EDU. 86400 IN A 129.170.192.44 mansfield2.cs.Dartmouth.EDU. 86400 IN A 129.170.212.67 aeolus.cs.Dartmouth.EDU. 86400 IN A 129.170.213.128 nickwaket2.cs.Dartmouth.EDU. 86400 IN A 129.170.210.10 dns-ext1.dartmouth.edu. 162060 IN A 129.170.170.2 dns-ext2.dartmouth.edu. 162060 IN A 129.170.170.10 This response is good to send back to the client (and this is the first packet that goes to the client, in all of the above). Note that there's no "aa" flag here. My server is not authoritative for this domain, i.e., does not hold the domain configuration files (a.k.a. "zone files"). It merely found this out, and will cache the response: -------------------[ 129.170.213.53 -> 72.95.x.x ]------------------- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16884 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 9, ADDITIONAL: 7 ;; QUESTION SECTION: ;www.cs.dartmouth.edu. IN A ;; ANSWER SECTION: www.cs.dartmouth.edu. 43200 IN CNAME katahdin.cs.dartmouth.edu. katahdin.cs.Dartmouth.EDU. 86400 IN A 129.170.213.101 ;; AUTHORITY SECTION: cs.dartmouth.edu. 28800 IN NS aeolus.CS.Dartmouth.EDU. cs.dartmouth.edu. 28800 IN NS dns-ext2.dartmouth.edu. cs.dartmouth.edu. 28800 IN NS mansfield2.CS.Dartmouth.EDU. cs.dartmouth.edu. 28800 IN NS mansfield.CS.Dartmouth.EDU. cs.dartmouth.edu. 28800 IN NS dns-ext1.dartmouth.edu. cs.dartmouth.edu. 28800 IN NS CS.Dartmouth.EDU. cs.dartmouth.edu. 28800 IN NS ns2.Dartmouth.Edu. cs.dartmouth.edu. 28800 IN NS nickwaket2.CS.Dartmouth.EDU. cs.dartmouth.edu. 28800 IN NS ns1.dartmouth.edu. ;; ADDITIONAL SECTION: cs.dartmouth.edu. 28800 IN A 129.170.212.26 aeolus.cs.dartmouth.edu. 28800 IN A 129.170.213.128 dns-ext1.dartmouth.edu. 28800 IN A 129.170.170.2 dns-ext2.dartmouth.edu. 28800 IN A 129.170.170.10 mansfield.cs.dartmouth.edu. 28800 IN A 129.170.192.44 mansfield2.cs.dartmouth.edu. 28800 IN A 129.170.212.67 nickwaket2.cs.dartmouth.edu. 28800 IN A 129.170.210.10 And now my browser can finally connect() to www.cs.dartmouth.edu .