DNS查询默认依靠UDP传输,这套规则自1983年确定之后一直沿用至今。打开网页,浏览器向DNS服务器询问example.com对应的IP,请求一般封装成单个UDP包发送,服务器回复UDP包,整个交互结束。没有握手流程,不维持连接状态,响应速度极快。
DNS选用UDP的原因,在于单次查询数据包体量很小。请求包只有几十字节,响应包大多几百字节。如果使用TCP,光是三次握手就需要一次半往返,服务器还要为每个连接分配内存、维护序列号、处理重传队列。全球每天万亿级别DNS查询,全部切换TCP,根服务器、顶级域名服务器无法承载。UDP属于无状态协议,服务器收到请求,完成查询直接返回响应,不保存会话信息。单台设备能够承载的并发请求数量,比TCP高出一个数量级。

UDP存在明显短板,传输不保证可靠性。数据包可能丢失、乱序、截断。DNS依靠应用层重试机制处理这类问题。客户端发送查询请求,等待一段时间没有收到响应,就重新发起请求,一般重试两到三次,间隔逐步拉长。这套机制不算完美,但足够使用,DNS数据包体积小,丢包概率低,重试成本不高。
TCP在DNS体系里不是完全无用,存在几种场景必须启用TCP。
第一种,响应数据包过大。UDP的DNS响应默认上限512字节。超过这个阈值,服务器截断响应内容,在包头标记TC标志位。客户端检测到截断标记,切换TCP重新查询。后续EDNS0扩展出现,允许客户端声明可接收更大UDP包,一般支持1232字节或者4096字节。数据包超过这个上限,依旧需要TCP传输。DNSSEC签名数据、长段TXT记录、多条MX记录,很容易超出UDP包上限。
第二种,区域数据同步。主DNS服务器和从DNS服务器同步完整区域数据,使用AXFR、IXFR协议。这类场景传输数据量大,可靠性要求高,只能依靠TCP,UDP无法承载这么大规模的数据同步。
第三种,网络策略限制。部分防火墙直接封禁UDP 53端口,只放行TCP 53端口。这种环境下DNS查询只能走TCP。这类情况不算普遍,但企业内网、部分运营商网络会出现。
还有一点容易混淆,DNS的TCP和UDP共用53端口。不是UDP占用53,TCP使用54,两者端口号都是53。客户端优先尝试UDP,响应截断或者超时,自动切换TCP,这个切换过程对用户透明,不会被感知。
现代加密DNS,DoT和DoH底层基于TCP。DoT把DNS查询封装在TLS协议内,TLS构建在TCP之上。DoH将DNS请求封装进HTTPS,HTTPS同样依托TCP。但这属于加密传输层实现,和传统DNS选择UDP或TCP不属于同一层面。传统DNS优先UDP的原则,不适用于加密DNS,加密握手本身就依赖TCP保障可靠传输。
准确描述:DNS默认使用UDP,特定场景切换TCP。UDP是默认方案,TCP作为备选。这套设计兼顾延迟与并发承载能力,四十多年过去依旧稳定有效。