DNS, UDP, IP Anycast, and All That
DNS prefers UDP. There are times when DNS must run on TCP (request or response size exceeds a single packet, perhaps due to too many response records), but UDP is perferred if possible. The reasons are
- Constraints from IP Anycasts that favor stateless applications such as DNS.
- Performance gain with UDP over TCP (2 vs 11 IP packets, no connection state management).
Anycast is one of the five addressing methods in IP, where multiple endpoint destinations share the same address. A request to such address expects only one response from any of the destinations. Routers may select the desired path based on costs, latency, and congestion. Another addressing method, Unicast address uniquely identifies a single receiver endpoint.
Anycast can be implemented by using Border Gateway Protocol (BGP) and Unicast. Multiple hosts (likely in different regions) are given the same unicast IP address. Different routes to the address are advertised through BGP, as if they are alternative routes to the same destination when in fact they actually route to different destinations with the same address. As usual, routers select a route by whatever metric (cost, congestion, distance, etc). Selecting a route in this design amounts to selecting a destination.
However, routing changes could break open connections to an anycast address, since IP packets could be routed to a different host that has no context on the connection state (such as TCP sequence numbers). With a normal unicast address, a routing change is not a problem at all, as packets eventually arrive at the same destination.
Hence, anycast is often used with connection-less protocols to provide high availability and load balancing for stateless services. DNS is a great fit. The root name servers need to be accessible at a well-known address (or we need another name server to find these name servers but what is the address to that name server?). The actual backend serving the query should be as close as possible to reduce response latency (as DNS lookup is often in the hot path before TCP, TLS, and finally HTTP).
UDP is best-effort (unreliable) and packets may be delivered out-of-order. However, a DNS query usually fits in a single packet and does not require an ordered byte stream. Hence, out-of-order delivery is not an issue; checksum and retransmission are enough to ensure integrity. In comparison, queries over TCP require 11 IP packets to complete:
- Three-way handshake to establish connection (SYN, SYN-ACK, ACK)
- Query by client, ACK by server
- Response by server, ACK by client
- Four-way handshake to close connection (FIN, ACK, FIN, ACK)
Using UDP allows the name server to scale better because it does not allocate or manage connection states, such as Receive and Send buffers, Sequence and Acknowledge Numbers, and flow-control and congestion-control parameters, etc.