DNS 支持 TCP 和 UDP 双协议,但为何偏偏只钟情 UDP?

一、前言之前在聊到 App 网络优化时,聊到通过 HTTPDNS 替换掉传统的 DNS 解析,来达到网络优化的效果 。其中提到 DNS 解析,是支持 UDP 和 TCP 双协议的 。
但是细心的朋友通过 wireshark、sniffer、tcpdump 等抓包工具分析,会发现基本上所有客户端发起 DNS 查询的场景下,都只使用到了 UDP 协议 。
那在 DNS 中,TCP 协议在什么场景下才会用到呢?
今天我们就来聊聊,DNS 的 TCP 的使用场景 。
二、DNS2.1 什么是 DNS
先来简单了解一下 DNS 。
在网络的世界中,每个有效的域名背后都有为其提供服务的服务器,而我们网络通信的首要条件,就是知道服务器的 IP 地址 。
但是记住域名(网址)肯定是比记住 IP 地址简单 。如果有某种方法,可以通过域名,查到其提供服务的服务器 IP 地址,那就非常方便了 。这里就需要用到 DNS 服务器以及 DNS 解析 。
DNS(Domain Name System),它的作用就是根据域名,查出对应的 IP 地址,它是 HTTP 协议的前提 。只有将域名正确的解析成 IP 地址后,后面的 HTTP 流程才可以继续进行下去 。
DNS 同时占用了 UDP 和 TCP 的 53 端口,但是大多数情况下,DNS 查询都只使用到了 UDP,而 TCP 只在一些特殊情况下才会被使用到 。
简单来说,DNS 使用 TCP 的情况,只有两种:

  1. DNS 查询响应报文大于 512 字节时 。
  2. DNS 主、辅助服务器之间,进行区域传送时 。
使用 TCP 的场景,基本上就是以上两种场景,当然,如果客户端主动发起一个 TCP 的 DNS 查询,也会使用 TCP 协议,这就不在讨论的范围内了 。
2.2 DNS 响应报文大于 512 字节
说到 DNS 响应报文,先来看看 DNS 数据包的结构,对于 DNS 来说,请求报文和响应报文的结构是一样的 。
DNS 支持 TCP 和 UDP 双协议,但为何偏偏只钟情 UDP?

文章插图
 
这其中,我们主要关注 Flags 这个标志位的结构 。
DNS 支持 TCP 和 UDP 双协议,但为何偏偏只钟情 UDP?

文章插图
 
在 Flags 中,每个字段都有其自己的含义,在这里我们做重关注 QR 和 TC 两个字段 。
  • QR 是一个 Bit,用于标识当前是查询报文(0)还是响应报文(1) 。
  • TC 也是一个 Bit,当它的值为 1 时,表示当前响应报文总长度,已经超过 512 字节,所以做了截断处理,只返回前 512 个字节 。
当遇到这种情况时,DNS 解析器会使用 TCP 来重发原来的查询请求,UDP 要求相应报文在 512 字节以内,而 TCP 则没有此限制,TCP 能用多个报文段来传送任意长度的用户数据 。
DNS 查询是一个过程复杂,但是结果简单的过程 。通常返回的数据不会大于 512 字节,这也就是为什么我们通过抓包的手段,得到的结果都是 DNS 在使用 UDP 协议 。
需要注意的是,在实际使用中,很多 DNS 服务器在进行配置的时候,就把 TCP 查询包的方式关闭,仅支持 UDP 查询包 。
2.3 DNS 主、辅助服务器的区域传送
DNS 服务器,在设计时就要求一定要是高可用、高并发和分布式的服务器,它被分为多个层次结构,分别是根 DNS 服务器、顶级域 DNS 服务器、权威 DNS 服务器 。
这三类 DNS 服务器,组成一种类似树的结构 。
DNS 支持 TCP 和 UDP 双协议,但为何偏偏只钟情 UDP?

文章插图
 
在这个"树"中,一个独立管理的 DNS 子树,称为一个区域(zone) 。一个 DNS 服务器负责管理一个或多个区域,为了满足高可用,一个区域的管理者必须为该区域提供一个主 DNS 服务器和至少一个辅助 DNS 服务器 。
主 DNS 服务器和辅助 DNS 服务器,必须是独立和冗余的,以便当某个 DNS 服务器发生故障时,不会影响该区域的 DNS 查询 。
既然 DNS 服务器有主和辅助之分,那必然面临了数据同步的情况,我们将辅助服务器从主服务器同步信息的动作,称为区域传送,而在触发区域传送试,使用的就是 TCP 协议 。
触发 DNS 区域传送的情况有两种:
  1. 新上线一台辅助服务器,会从主服务器执行区域传送,进行同步数据 。
  2. 辅助服务器会定时(通常是 3 小时),向主服务器查询,以便了解到主服务器的数据是否发生变动,如果变动,也会触发一次区域传送 。
区域传送会使用 TCP 协议,一方面是为了保证数据的可靠,另一方面此时传送的数据,也远比一个查询或响应大的多 。
三、小结时刻到此我们就了解清楚了,虽然 DNS 服务器支持 TCP 和 UDP 双协议,但是通常我们在做 DNS 查询的时候,也只用到了 UDP 协议 。


推荐阅读