how a dns query works [closed]

DNS resolution can get pretty hairy when you start to consider things like caching and anycast, but let's keep it simple for now.

Here are snippets of digs next to snippets of tcpdumps of a query for www.google.com to a freshly started nameserver, so no caching is being used. I've trimmed some of the timestamps for legibility.

First, the local nameserver (here 192.168.10.10) asks one of the root servers (in this case h.root-servers.net, 128.63.2.53) the query "what is the A record for www.google.com?" h.root-servers.net is not authoritative for www.google.com, but it does have a delegation for .com, so it returns that.

192.168.10.10.17203 > 128.63.2.53.53: 29969 [1au] A? www.google.com. (43)
128.63.2.53.53 > 192.168.10.10.17203: 29969- 0/15/16 (719)

;; QUESTION SECTION:
;www.google.com.                        IN      A

;; AUTHORITY SECTION:
com.                    172800  IN      NS      a.gtld-servers.net.
com.                    172800  IN      NS      b.gtld-servers.net.
com.                    172800  IN      NS      c.gtld-servers.net.
com.                    172800  IN      NS      d.gtld-servers.net.
com.                    172800  IN      NS      e.gtld-servers.net.
com.                    172800  IN      NS      f.gtld-servers.net.
com.                    172800  IN      NS      g.gtld-servers.net.
com.                    172800  IN      NS      h.gtld-servers.net.
com.                    172800  IN      NS      i.gtld-servers.net.
com.                    172800  IN      NS      j.gtld-servers.net.
com.                    172800  IN      NS      k.gtld-servers.net.
com.                    172800  IN      NS      l.gtld-servers.net.
com.                    172800  IN      NS      m.gtld-servers.net.

Second, the local nameserver then chooses one of the nameservers from the list returned by h.root-servers.net and sends the same query: "what is the A record for www.google.com?" In this case the nameserver queried was f.gtld-servers.net (192.35.51.30). f.gtld-servers.net, which is authoritative for .com, has responded with the nameserver delegations for the zone google.com

192.168.10.10.65182 > 192.35.51.30.53: 58632 [1au] A? www.google.com. (43)
192.35.51.30.53 > 192.168.10.10.65182: 58632- 0/4/5 (179)

;; QUESTION SECTION:
;www.google.com.                        IN      A

;; AUTHORITY SECTION:
google.com.             172800  IN      NS      ns2.google.com.
google.com.             172800  IN      NS      ns1.google.com.
google.com.             172800  IN      NS      ns3.google.com.
google.com.             172800  IN      NS      ns4.google.com.

Getting closer! Now the local nameserver picks one of the nameservers in the last response and asks it the same question. In this case, it asks ns2.google.com (216.239.34.10). ns2.google.com responds that www.google.com is actually a CNAME (canonical name) record for www.l.google.com

192.168.10.10.4767 > 216.239.34.10.53: 15830 [1au] A? www.google.com. (43)
216.239.34.10.53 > 192.168.10.10.4767: 15830*- 6/0/0 CNAME[|domain]

;; QUESTION SECTION:
;www.google.com.                        IN      A

;; ANSWER SECTION:
www.google.com.         604800  IN      CNAME   www.l.google.com.

Very close! Now we just need the address of www.l.google.com. Now because we already know the nameservers for google.com, we just ask one of them. In this case, we ask ns3.google.com (216.239.36.10) "what is the A record for www.l.google.com.?" It responds with the address, and we have our answer:

192.168.10.10.63657 > 216.239.36.10.53: 62511 [1au] A? www.l.google.com. (45)
216.239.36.10.53 > 192.168.10.10.63657: 62511*- 5/0/0 A[|domain]

;; QUESTION SECTION:
;www.l.google.com.              IN      A

;; ANSWER SECTION:
www.l.google.com.       300     IN      A       74.125.232.116
www.l.google.com.       300     IN      A       74.125.232.112
www.l.google.com.       300     IN      A       74.125.232.115
www.l.google.com.       300     IN      A       74.125.232.113
www.l.google.com.       300     IN      A       74.125.232.114

Huzzah!

Anyway, I hope that's enough to get your started. There are a lot of great resources out there. The O'Reilly book "DNS and BIND" is very useful.

I highly highly highly recommend installing dig to use for seeing how the DNS queries go. For example, you can use dig +trace to easily see the delegation path to a host:

; <<>> DiG 9.7.0-P1 <<>> +trace www.google.com
;; global options: +cmd
.                       516930  IN      NS      k.root-servers.net.
.                       516930  IN      NS      g.root-servers.net.
.                       516930  IN      NS      h.root-servers.net.
.                       516930  IN      NS      j.root-servers.net.
.                       516930  IN      NS      a.root-servers.net.
.                       516930  IN      NS      m.root-servers.net.
.                       516930  IN      NS      b.root-servers.net.
.                       516930  IN      NS      f.root-servers.net.
.                       516930  IN      NS      d.root-servers.net.
.                       516930  IN      NS      c.root-servers.net.
.                       516930  IN      NS      l.root-servers.net.
.                       516930  IN      NS      i.root-servers.net.
.                       516930  IN      NS      e.root-servers.net.
;; Received 244 bytes from 127.0.0.1#53(127.0.0.1) in 1 ms

com.                    172800  IN      NS      i.gtld-servers.net.
com.                    172800  IN      NS      j.gtld-servers.net.
com.                    172800  IN      NS      c.gtld-servers.net.
com.                    172800  IN      NS      l.gtld-servers.net.
com.                    172800  IN      NS      d.gtld-servers.net.
com.                    172800  IN      NS      h.gtld-servers.net.
com.                    172800  IN      NS      a.gtld-servers.net.
com.                    172800  IN      NS      e.gtld-servers.net.
com.                    172800  IN      NS      b.gtld-servers.net.
com.                    172800  IN      NS      g.gtld-servers.net.
com.                    172800  IN      NS      f.gtld-servers.net.
com.                    172800  IN      NS      k.gtld-servers.net.
com.                    172800  IN      NS      m.gtld-servers.net.
;; Received 492 bytes from 202.12.27.33#53(m.root-servers.net) in 45 ms

google.com.             172800  IN      NS      ns2.google.com.
google.com.             172800  IN      NS      ns1.google.com.
google.com.             172800  IN      NS      ns3.google.com.
google.com.             172800  IN      NS      ns4.google.com.
;; Received 168 bytes from 192.33.14.30#53(b.gtld-servers.net) in 42 ms

www.google.com.         604800  IN      CNAME   www.l.google.com.
www.l.google.com.       300     IN      A       74.125.232.115
www.l.google.com.       300     IN      A       74.125.232.113
www.l.google.com.       300     IN      A       74.125.232.116
www.l.google.com.       300     IN      A       74.125.232.114
www.l.google.com.       300     IN      A       74.125.232.112
;; Received 132 bytes from 216.239.34.10#53(ns2.google.com) in 131 ms

Notice how similar it is to the trace of the query earlier? Hope that helps.


It is slightly more complicated as DNS is quite heavily cached. Your local machine may even have the data cached and the lookup goes no further than that.

Your machine will query it's own cache and if that fails it will query the primary DNS server it has been told about. This may be a caching DNS server and my have the result in it's cache in which case the record is returned to you and the lookup ends. It is also most likely a recursive DNS server and will now do the leg work for your machine.

If the primary DNS server doesn't have the information it will query the root name servers they will respond with (in your example) the TLD name servers for .com

A query will be sent to the .com TLD servers which will respond with the address of the authoritative name server for google.com

A query will be sent to the authoritative name server for google.com requesting the www.google.com record. This will be found and returned to the primary DNS server which will cache it and return the record to you.