之前在聊到 App 网络优化时,聊到通过 HTTPDNS 替换掉传统的 DNS 解析,来达到网络优化的效果。其中提到 DNS 解析,是支持 UDP 和 TCP 双协议的。
但是细心的朋友通过 wireshark、sniffer、tcpdump 等抓包工具分析,会发现基本上所有客户端发起 DNS 查询的场景下,都只使用到了 UDP 协议。
那在 DNS 中,TCP 协议在什么场景下才会用到呢?
今天我们就来聊聊,DNS 的 TCP 的使用场景。
2.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 的情况,只有两种:
使用 TCP 的场景,基本上就是以上两种场景,当然,如果客户端主动发起一个 TCP 的 DNS 查询,也会使用 TCP 协议,这就不在讨论的范围内了。
2.2 DNS 响应报文大于 512 字节
说到 DNS 响应报文,先来看看 DNS 数据包的结构,对于 DNS 来说,请求报文和响应报文的结构是一样的。
这其中,我们主要关注 Flags 这个标志位的结构。
在 Flags 中,每个字段都有其自己的含义,在这里我们做重关注 QR 和 TC 两个字段。
当遇到这种情况时,DNS 解析器会使用 TCP 来重发原来的查询请求,UDP 要求相应报文在 512 字节以内,而 TCP 则没有此限制,TCP 能用多个报文段来传送任意长度的用户数据。
DNS 查询是一个过程复杂,但是结果简单的过程。通常返回的数据不会大于 512 字节,这也就是为什么我们通过抓包的手段,得到的结果都是 DNS 在使用 UDP 协议。
需要注意的是,在实际使用中,很多 DNS 服务器在进行配置的时候,就把 TCP 查询包的方式关闭,仅支持 UDP 查询包。
2.3 DNS 主、辅助服务器的区域传送
DNS 服务器,在设计时就要求一定要是高可用、高并发和分布式的服务器,它被分为多个层次结构,分别是根 DNS 服务器、顶级域 DNS 服务器、权威 DNS 服务器。
这三类 DNS 服务器,组成一种类似树的结构。
在这个"树"中,一个独立管理的 DNS 子树,称为一个区域(zone)。一个 DNS 服务器负责管理一个或多个区域,为了满足高可用,一个区域的管理者必须为该区域提供一个主 DNS 服务器和至少一个辅助 DNS 服务器。
主 DNS 服务器和辅助 DNS 服务器,必须是独立和冗余的,以便当某个 DNS 服务器发生故障时,不会影响该区域的 DNS 查询。
既然 DNS 服务器有主和辅助之分,那必然面临了数据同步的情况,我们将辅助服务器从主服务器同步信息的动作,称为区域传送,而在触发区域传送试,使用的就是 TCP 协议。
触发 DNS 区域传送的情况有两种:
区域传送会使用 TCP 协议,一方面是为了保证数据的可靠,另一方面此时传送的数据,也远比一个查询或响应大的多。
到此我们就了解清楚了,虽然 DNS 服务器支持 TCP 和 UDP 双协议,但是通常我们在做 DNS 查询的时候,也只用到了 UDP 协议。
TCP 只有在以下两种情况下,才会被使用到:
DNS 查询和响应,通常都在广域网上通信,对于 DNS 客户端,保证好的重传和超时机制,就显得尤为重要了。