DNS 为什么主要用 UDP?什么时候用 TCP?
简化版
DNS 查询主要用 UDP(端口 53),因为 DNS 查询「一问一答、数据小、要快」——UDP 无连接、开销小,省去了 TCP 三次握手的往返,一个包就搞定,丢了重查即可。但在响应过大(超过限制,如 DNSSEC、大量记录)或**区域传送(zone transfer)**时改用 TCP,因为需要可靠、有序地传输大数据。
详细版
为什么默认 UDP:
- DNS 查询是典型的短小的请求-响应:一个查询包问、一个响应包答;
- 传统 DNS 响应限制在 512 字节内,一个 UDP 包就装得下;
- UDP 无需建连,省去 TCP 三次握手的往返,解析更快、服务器开销更小(能扛更高并发);
- 丢包了?客户端超时重查一次即可,代价很低。
什么时候用 TCP:
- 响应超过 512 字节:响应包在 UDP 里放不下会被「截断」(标志位 TC=1),客户端就改用 TCP 重发查询以获取完整响应。常见于返回大量记录、DNSSEC(带签名,数据大)等。
- 区域传送(Zone Transfer,AXFR):主从 DNS 服务器之间同步整个域的记录,数据量大且必须完整可靠,用 TCP。
(现代有 EDNS0 扩展,允许 UDP 响应超过 512 字节,减少了回退到 TCP 的情况。)
完整版教学
一、为什么 UDP 是 DNS 的最佳拍档
DNS 查询的特点,恰好和 UDP 的优势完美契合:
- 数据小:一次查询 + 一次响应,通常几十到几百字节,UDP 一个包就够;
- 要快:解析是访问网站的第一步,越快越好。UDP 无连接,直接发包,省掉了 TCP 三次握手的一个 RTT——这对解析速度很关键;
- 量大:DNS 服务器要扛海量查询,UDP 无连接、无状态,服务器不用为每个查询维护连接,能扛更高并发;
- 能容忍丢包:DNS 有超时重查机制,丢一个查询包重发即可,不需要 TCP 那套复杂的可靠保证。
如果 DNS 用 TCP,每次查询都要先三次握手、再四次挥手,光握手就多一个 RTT,且服务器要维护大量连接——对「短小、高频、要快」的 DNS 查询来说得不偿失。所以用 UDP 是权衡后的最优解。
二、512 字节:一个历史限制
传统 DNS 规定 UDP 响应最大 512 字节。这是早期为了保证 UDP 包不被分片(IP 分片不可靠)定的保守值。
当响应装不下 512 字节时,服务器会返回一个截断(TC=1)标志的响应,等于告诉客户端「内容太多,UDP 装不下」。客户端看到这个标志,就改用 TCP 重新查询——TCP 能可靠地传输任意大小的数据,拿到完整响应。
三、什么场景响应会变大 → 触发 TCP
- DNSSEC:为防篡改,DNSSEC 给记录加了数字签名,响应里带一堆签名数据,很容易超过 512 字节;
- 大量记录:一个域名配了很多 A 记录(如大型 CDN 的轮询)、或 TXT 记录很长;
- 区域传送(AXFR/IXFR):从服务器要从主服务器同步整个域的所有记录,数据量大、必须完整可靠——这种必须用 TCP,而且是 DNS 用 TCP 最典型的场景。
四、EDNS0:让 UDP 也能传大响应
每次超 512 字节就回退 TCP 太影响性能。EDNS0(扩展 DNS) 允许客户端在查询时声明「我能接收更大的 UDP 响应」(如 4096 字节),于是很多本来要回退 TCP 的大响应,现在用 UDP 也能一次传完,减少了 TCP 回退、提升了效率。现代 DNS(尤其配合 DNSSEC)普遍启用 EDNS0。
五、常见误区
- ❌ 以为 DNS 只用 UDP——查询默认 UDP,但响应过大或区域传送时用 TCP。
- ❌ 以为 DNS 从不用 TCP——区域传送必须用 TCP,DNSSEC 大响应也常用。
- ❌ 以为用 UDP 会因丢包不可靠——DNS 有超时重查兜底,丢了重发即可,代价低。
- ❌ 忽略 EDNS0——它让 UDP 能传更大响应,减少 TCP 回退,是现代 DNS 的标配。
六、常见误区与追问
| 考点 | 正确口径 |
|---|---|
| UDP 53 | 默认查询,开销小、延迟低 |
| TCP 53 | 区域传送、大响应、截断重试 |
| EDNS0 | 扩展 UDP 可承载大小,减少截断 |
normal query: UDP/53
if response TC=1:
retry with TCP/53
zone transfer AXFR:
TCP/53
DNS 默认用 UDP 是为了快,不代表 DNS 不能用 TCP;遇到大包和可靠传输需求就会切 TCP。
- 误区:DNS 只能用 UDP。 普通查询默认 UDP,但 TCP 也用于截断重试、区域传送和部分安全场景。
- 误区:UDP 不可靠所以 DNS 结果不可信。 DNS 应用层有事务 ID、超时重试和校验机制;可信性还要看 DNSSEC、链路和解析器。
- 误区:TCP 一定比 UDP 更适合所有 DNS。 TCP 建连有额外往返和状态成本,海量短查询默认 UDP 更合适。
- 追问:TC 标志是什么? 响应被截断时设置 TC=1,客户端应改用 TCP 重新查询完整结果。
- 追问:DNSSEC 为什么更容易触发 TCP? 签名记录会增大响应体,超过 UDP 承载能力时需要 TCP。
- 追问:DoH/DoT 还是 53 端口吗? DoT 常用 853,DoH 走 HTTPS 443,它们是加密 DNS 传输方式。
七、加强记忆
DNS 查询默认用 UDP(端口 53),因为查询短小、要快、量大、能容忍丢包,UDP 无连接省去握手往返、开销小、扛并发。响应超过 512 字节(DNSSEC、大量记录)会截断并回退 TCP,区域传送(同步整个域)也必须用 TCP。EDNS0 扩展让 UDP 能传更大响应、减少 TCP 回退。