This document lists categorized answers and questions with links to the relevant documentation.
You may have spotted the 512 in something like the following (after EDNS ... udp:
):
$ dig example.com @127.0.0.1
; <<>> DiG 9.11.5-P4-5.1+deb10u3-Debian <<>> example.com @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20155
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;example.com. IN A
;; ANSWER SECTION:
example.com. 43200 IN A 93.184.216.34
;; Query time: 86 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Apr 15 13:56:34 CEST 2021
;; MSG SIZE rcvd: 56
and wonder ‘why is the Recursor using a bufsize of 512? Did we not decide on a Flag Day, all together, that we would use 1232?’
The EDNS buffer size in a DNS packet, generated by side A, tells the recipient of that packet (side B) the maximum packet size that side A will accept from side B. So, when the Recursor talks to an Authoritative, the Recursor reports the buffer size the Authoritative is allowed to use to it - usually 1232 (edns-outgoing-bufsize). But the example above is the Recursor responding to a client, and it is telling the client ‘from you, I accept packets of up to 512 bytes’. Or, to say it differently, the Recursor is telling the client that questions must fit in 512 bytes. This is fine for the Recursor - unlike an Authoritative, that might need to handle big UPDATE requests, the Recursor really only answers simple questions from clients, and those always comfortably fit in 512 bytes, because the maximum length of a DNS name is 256 bytes.
Similarly, the maximum size of a response from the Recursor to a client is governed by the buffer size sent by the client (in dig
, you can see that number by doing dig +qr
), and the udp-truncation-threshold setting in the Recursor configuration.
To see the buffer size the Recursor is sending to authoritatives, you can ask the question below, which gets sent to an authoritative server reporting in a TXT answer record what it saw in the query:
$ dig txt header.lua.powerdns.org +short @127.0.0.1
"id: 52938, aa: false, rd: false, ad: false, cd: false, do: true, ednsbufsiz: 1232, tcp: false"
Or, in a diagram:
udp-truncation-threshold edns-outgoing-bufsize
[default is 1232] [default is 1232]
| |
+------+ v +----------+ v +------------+
| stub | <=========> | recursor | <===================> | responders |
+------+ +----------+ +------------+
^
|
client bufsize (stub => recursor)
bufsize reported to client (recursor => stub [always 512])
On startup, the Recursor uses root hints to resolve the names and addresses of the root name servers and puts the record sets found into the record cache. This is needed to be able to resolve names, as the recursive algorithm starts at the root (using cached data) and then tries to resolve delegations until it finds the name servers that are authoritative for the domain in question.
If the hint-file is not set, it wil use a compiled-in table as root hints.
Starting with version 4.6.2, if hint-file is set to no
, the Recursor will not fill the cache with root data.
This can be used in special cases, e.g. when all queries are forwarded.
Note that the root hints and resolved root data can differ if the root hints are outdated. As long as at least one root server mentioned in the root hints can be contacted, this mechanism will produce the desired record sets corresponding to the actual root server data.
Periodically, based on the max-cache-ttl, the Recursor will refetch the root data using data in its cache. If that does not succeed, it wil fall back to using the root hints to fill the cache with root data. Prior to version 4.7.0, the period for re-fetching root data was max-cache-ttl divided by 12, with a minimum of 10 seconds. Starting with version 4.7.0, the period is adaptive, starting at 80% of max-cache-ttl, reducing the interval on failure.
There is another detail: after refreshing the root records, the Recursor will resolve the NS
records for the top level domain of the root servers.
For example, in the default setup the root name servers are called [a-m].root-servers.net
, so the Recursor will resolve the name servers of the .net
domain.
This is needed to correctly determine zone cuts to be able to decide if the .root-servers.net
domain is DNSSEC protected.