Settings

Theme

Why is DNS resolution via UDP slower than TCP on Mac?

9 points by SkyLinx 3 years ago · 25 comments · 1 min read


My understanding is that DNS queries via UDP (the default) should be faster, but I am seeing the opposite on two Macs I own, and other 3 people I have asked who are also on Mac, see exactly the same thing. It's weird, but queries over UDP are 3-5 times slower than queries over TCP. I cannot reproduce this on my Linux servers for example.

On my Macs I switched to DNS over TLS which is much faster than the default UDP querying for me, but I am still curious.

Can readers with Macs try as well? To test, I run the command `dig @1.1.1.1 somedomain.com` to test with UDP (with Cloudflare's public DNS in this case, and any domain you want), and the same command but with the additional argument`+tcp` to query over TCP. Try each command a few times. Which one is faster for you? UDP or TCP?

Trying to understand if it's a Mac issue. Thanks in advance!

LinuxBender 3 years ago

I would rule out UDP vs TCP before testing DNS as they may have a bug in the network stack from a recent kernel update and that should be ruled out first.

[Edit 3] I am seeing the same thing to 1.1.1.1. But I can also reproduce this to a few other places on the internet... Yet I do not see this to a handful of UDP listeners I have throughout the US. It seems to be route specific but not CF specific. Perhaps someone here has a 1thousand eyes account and happens to have TCP and UDP probes around the world? The "nc" tests should be performed against all the open resolvers and many authoritative servers around the world to compare results.

Simple tests can be done with "nc" to take dig out of the picture. netcat should be available in macports and homebrew. If not, nmap also has a version of netcat. I suggesting taking dig out of the picture as it overrides the OS tcp and socket default options.

    time nc -vnz -w1 1.1.1.1 53
    time nc -vnzu -w1 1.1.1.1 53
The same tests could also be done against any daemons listening for UDP on something other than port 53 to rule out mac or other devices on your network intercepting port 53 and trying to do something intelligent with it.
  • LinuxBender 3 years ago

    I think nc has changed behavior. Using nmap I get more consistent results.

        nmap -iL /dev/shm/list.txt -sU -p53
        nmap -iL /dev/shm/list.txt -sT -p53
    
    /dev/shm/list.txt being a list of open resolvers and other UDP listeners on the internet. Give nmap a shot if testing.
  • xrayarx 3 years ago

      % time nc -vnz 1.1.1.1 53
      Connection to 1.1.1.1 port 53 [tcp/*] succeeded!
      nc -vnz 1.1.1.1 53  0,00s user 0,00s system 8% cpu 0,073 total
    
      % time nc -vnzu 1.1.1.1 53
      Connection to 1.1.1.1 port 53 [udp/*] succeeded!
      nc -vnzu 1.1.1.1 53  0,00s user 0,00s system 61% cpu 0,009 total
c0nsumer 3 years ago

Querying 1.1.1.1: TCP is 183 msec, UDP is 323 msec.

Querying my local DNS, a pi-hole instance running in Docker on a Synology DSM: TCP is 3 msec, UDP is 0 msec (per the dig output).

So my initial take is that DNS over UDP is faster on the local network and thus you need to start digging into why Cloudflare is behaving as it is, or maybe there's something with all the hops between you and there. Some transparent DNS proxy or something?

xrayarx 3 years ago

Can confirm. My guess would be that udp is slower because it is not encrypted and at some point providers started to inject answers for various purposes. That is why we now have these services that provide „secure„ dns, but what they are really doing is fingerprinting and collecting data.

  • SkyLinxOP 3 years ago

    I have the same issue with VPNs though, so it can't be my provider I think?

    • xrayarx 3 years ago

      I wanted to try dtrace. Maybe that would lead to some clues. Unfortunately I am on an M1 and I can’t get it working.

citrin_ru 3 years ago

Does dig takes into account time it takes to establish a TCP connection? If it counts only time it takes to send and receive a response (after the connection has been established) there should be no statistically significant difference in the result.

  • citrin_ru 3 years ago

    Looks like dig discounts TCP connect time. In drill I see TCP being 2 times slower than UDP (which is what I would expect) but dig shows approximately the same numbers with and without +tcp.

    • benmmurphy 3 years ago

      if you look at the query in Wireshark from TCP SYN to the DNS response packet was ~11ms for me and dig claimed it was 3ms. kind of surprising that OP found it ALWAYS faster. I had some queries that were faster over UDP. when you are not counting the TCP connection setup I would expect them to be close to the same.

    • SkyLinxOP 3 years ago

      Are you on Mac? What is drill?

      • citrin_ru 3 years ago

        drill vs dig comparison was not form mac, but I expect them behave similarly on different platforms. drill is a dig-like utility from NLnet Labs, on Mac can be installed as part of ldns library e. g. using 'brew install ldns'

        • SkyLinxOP 3 years ago

          With Drill I get the same numbers with or without the -t argument for tcp. So it gives a different result from dig. Why?

          • citrin_ru 3 years ago

            How these number compare to ping RTT? On FreeBSD I have following numbers - ping: 12ms avg, drill: 13 msec (~RTT), drill -t: 25 msec (2*RTT)

svet_0 3 years ago

On Windows DNS/UDP/WiFi to 8.8.8.8 with query=www.google.com is 3-4ms

TCP is around ~10ms including overhead, 3ms excluding.

TLS is ~100ms including overhead, 5ms excluding.

1.1.1.1:

udp - 5ms

tcp - 15ms / 10ms

tls - 70ms / 4ms

Use a sniffer (e.g. wireshark) to get a better idea for timing, I wouldn't count on dig for that.

  • SkyLinxOP 3 years ago

    That's why I think it may be a problem on Macs, because I don't see the same issue on Linux either. I am not familiar with Wireshark. What should I be looking for? I tried but there's a lot of information for each packet.

    • svet_0 3 years ago

      Filter by "ip.addr == 1.1.1.1" and look at the "Time" column. With UDP you'll see 2 datagrams - request and response. TCP you'll see a SYN,SYNACK,ACK handshake and then 2 segments. TLS you'll see a longer handshake and then (encrypted) request and response (2 segments).

      • SkyLinxOP 3 years ago

        Wow now I am even more confused. The Time column shows 3.67 for UDP and 7.32 for TCP. This seems to suggest that UDP is faster, but dig commands show the opposite. Why is that?

coldtea 3 years ago

Your question in the title seems to be the opposite of what you write (you appear to ask: why is UDP DNS faster on the Mac)

ergonaught 3 years ago

I only see something similar when using wifi; disappears on ethernet.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection