How does the DNS protocol switch from UDP to TCP?

12,674

The client does not know in advance that the response will be too large, so it will query the server via UDP.
The server will respond via UDP and will include as much as possible and set the truncated header bit ("TC" http://www.networksorcery.com/enp/protocol/dns.htm).
The client can then resend the request via TCP and get the full response.

See also: https://www.rfc-editor.org/rfc/rfc5966

In the absence of EDNS0 (Extension Mechanisms for DNS 0) (see below), the normal behaviour of any DNS server needing to send a UDP response that would exceed the 512-byte limit is for the server to truncate the response so that it fits within that limit and then set the TC flag in the response header. When the client receives such a response, it takes the TC flag as an indication that it should retry over TCP instead.

And: https://www.ietf.org/rfc/rfc2181.txt

And as mentioned in the comments, of course DNS zone transfers are always using TCP.

Share:
12,674

Related videos on Youtube

StanTastic
Author by

StanTastic

I troubleshoot things.

Updated on September 18, 2022

Comments

  • StanTastic
    StanTastic over 1 year

    Before anyone asks: I've seen When do DNS queries use TCP instead of UDP? and it doesn't answer my question.

    All I keep hearing is "if the answer is too long, DNS will use TCP". This does not explain how it happens though.

    So here's the situation: DNS client asks for resolution of a record using UDP. The record is too long for UDP:

    1. server answers with specific opcode, to have client switch to TCP
    2. server doesn't answer at all, and client re-tries over TCP
    3. server opens TCP connection to client (stupid, if you count NAT, but who knows?)
    4. client somehow (?) 'knows' that given query should be run over TCP so it doesn't bother with UDP in the first place
    5. DNS pixies magically turn UDP into TCP when needed

    I've been looking all over the internet for the answer, but there's lot of noise (see above), and I can't seem to write proper Google query for that (nor can I find the info in RFCs, for that matter).

    • StanTastic
      StanTastic almost 9 years
      All I could find was in RFC5966: "A resolver SHOULD send a UDP query first, but MAY elect to send a TCP query instead if it has good reason to expect the response would be truncated if it were sent over UDP (with or without EDNS0) or for other operational reasons, in particular, if it already has an open TCP connection to the server.". When should resolver "expect" that the response will be truncated?
    • David Schwartz
      David Schwartz almost 9 years
      An obvious example would be if a previous request for the same record was too long to fit in a UDP datagram.
    • StanTastic
      StanTastic almost 9 years
      So there's an opcode that says 'truncated', right? And it switches then - basically what I thought, it's the most obvious solution.
    • MSalters
      MSalters almost 9 years
      Case (d) may be a wise choice if the query contains multiple "questions" (addresses to resolve). If you need to resolve 100 addresses, you're not going to be able to fit the response in a single UDP packet.
    • kasperd
      kasperd almost 9 years
      BTW. Saying 3. would be stupid because of NAT is not actually a valid argument because NAT did not exist when DNS was designed. If DNS had been done like your option 3., then it would have been stupid to make a NAT which could not handle that. But you could argue that 3. is problematic because it would require every DNS client to bind to a TCP port before sending any requests and somehow communicate to the DNS server where it is listening.
  • Matt Nordhoff
    Matt Nordhoff almost 9 years
    RFC 5966 also notes that TCP is always used for zone transfers.
  • faker
    faker almost 9 years
    @MattNordhoff Right, that's true and good to mention. This was more aimed at the 'how does the switch from UDP to TCP work?' angle. But I'll add it to the answer.
  • raja
    raja almost 9 years
    However if there is already a TCP connection it will only use TCP
  • StanTastic
    StanTastic almost 9 years
    Oh, that's interesting. So when does it fall back to UDP?
  • Barmar
    Barmar almost 9 years
    @JimB Are you sure about that? I don't think it keeps a persistent TCP connection open.
  • raja
    raja almost 9 years
    @Barmar I didn't say it kept a persistent connectionbut if one is open it will use that rather than start all over again