Why 13 DNS root servers?

November 10, 2013

dns

Updated. Thanks to Carsten Strotmann, who chimmed in. The maximum packet is 576 octects as specified in RFC 791. Removing the headers, leaves ~512 octets for the payload. See https://ripe67.ripe.net/presentations/112-2013-10-16-dns-protocol.pdf. Numbers slightly updated.

So why are there (only) 13 root-nameservers? See the updates below, this scheme came into use in the 90ies.

A priming query is a query that a nameserver performs when it starts up to get a list of the root nameserver IP addresses. This is done to validate (and possibly update) the built-in list of the addresses it has. In the early days of the DNS, the maximum packet size was set to 512 bytes, so this list needed to fit in 512 bytes.

The returned message looks something like this. Here I only list {a,b}.root-servers.net and delete some modern features as AAAA and OPT records.

;; QUESTION SECTION:
;.              IN  NS

;; ANSWER SECTION:
.           518400  IN  NS  a.root-servers.net.
.           518400  IN  NS  b.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

So how big is this message? The DNS packet header is 12 bytes. The size of the question section is:

  • root-label: 00, 1 byte;
  • class, 2 bytes and;
  • the qtype: 2 bytes.

In total 5 bytes. Now the size of one resource record in the answer section is:

  • root-label: 1 byte;
  • ttl: 4 bytes;
  • class: 2 bytes;
  • type: 2 bytes;
  • rdlength: 2 bytes
  • nameserver name: <1>a<12>root-servers<3>net<0>: 20 bytes.

Totals: 31 bytes. The other records can employ DNS compression, so subsequent records have the root-label, ttl, class, type, rdlength and then <1><letter><compression pointer>, which is 4 bytes, so this comes to: 15 bytes.

And the A record in the additional section comes to:

  • nameserver name: <1>a<12>root-servers<3>net<0>: 20 bytes;
  • ttl: 4 bytes;
  • class: 2 bytes;
  • type: 2 bytes;
  • rdlength: 2 bytes;
  • address: 4 bytes.

But here the name can be fully compressed, so instead of 20 bytes, we can use 2 bytes for the compression pointer. So this totals 16 bytes. Again the packet, but then only with the sizes:

12       ;; ->>HEADER<<-
 5       ;; QUESTION SECTION:
31 + 15n ;; ANSWER SECTION:
     16m ;; ADDITIONAL SECTION:

Usually m = n, so the equation becomes:

48 + 31n = 512
       n = 464 / 31 = 14.96

WTF, 14,9?

Update 1

According to @agercasa (Jaap Akkerhuis), Bill Manning said they wanted to be conservative and leave some room for future expansion.

Update 2

The original list didn’t use the root-servers.net suffix, but was smaller than 512 bytes anyhow. When the list was extended the root-servers.net suffix was created to save space (compression) and made it possible to have 14 root servers, of which 13 have been allocated. This predates anycast so a large® number of servers was needed, according to Bill Maning:

… this predates anycast, so it was thought prudent to wait to select all the remaining operators. as it turns out, the realignment did not go according to plan, VSGN has two and ICANN has one. the original idea was a second operator in asia and on in south america…

Also the step going from a mishmash of names to the ones with a common suffix and the 512-byte calculation was done in one step.

Update 3

@isomer dug up an old root hints file from BIND 4.9.2-940221.

;
;       This file holds the information on root name servers needed to
;       initialize cache of Internet domain name servers
;       (e.g. reference this file in the "cache  .  <file>"
;       configuration file of BIND domain name servers).
;
;       This file is made available by InterNIC registration services
;       under anonymous FTP as
;           file                /domain/named.root
;           on server           FTP.RS.INTERNIC.NET
;       -OR- under Gopher at RS.INTERNIC.NET
;           under menu          InterNIC Registration Services (NSI)
;              submenu          InterNIC Registration Archives
;           file                named.root
;
;       last update:    April 21, 1993
;       related version of root zone:   930421
;
.                        99999999 IN  NS    NS.INTERNIC.NET.
NS.INTERNIC.NET.         99999999     A     198.41.0.4
.                        99999999     NS    KAVA.NISC.SRI.COM.
KAVA.NISC.SRI.COM.       99999999     A     192.33.33.24
.                        99999999     NS    C.NYSER.NET.
C.NYSER.NET.             99999999     A     192.33.4.12
.                        99999999     NS    TERP.UMD.EDU.
TERP.UMD.EDU.            99999999     A     128.8.10.90
.                        99999999     NS    NS.NASA.GOV.
NS.NASA.GOV.             99999999     A     128.102.16.10
                         99999999     A     192.52.195.10
.                        99999999     NS    NS.NIC.DDN.MIL.
NS.NIC.DDN.MIL.          99999999     A     192.112.36.4
.                        99999999     NS    AOS.ARL.ARMY.MIL.
AOS.ARL.ARMY.MIL.        99999999     A     128.63.4.82
                         99999999     A     192.5.25.82
.                        99999999     NS    NIC.NORDU.NET.
NIC.NORDU.NET.           99999999     A     192.36.148.17
Root  Nameservers