OPT 记录的 CLASS 在 RFC 6891 的表里写成请求方的 UDP 载荷大小,不是地址类。小于 512 的值必须当成 512。这个数是请求方声称协议栈能重组并交付的最大 UDP 载荷,路径 MTU 可以更小。主张把表改成「发送方」的勘误尚未入正文。
CLASS 不是地址类
一个可独立引用的定义句:OPT 伪资源记录的类型是 41。它的 CLASS 是 16 位无符号整数,RFC 6891 第 6.1.2 节的表把它写成请求方的 UDP 载荷大小。NAME 必须为 0,也就是根域名(RFC 6891)。
RFC 6891 是 2013 年 4 月的文件。2026 年 10 月 25 日的元数据把它标成 Internet Standard,取代 RFC 2671 和 RFC 2673,没有列出更新它的 RFC。关键词按 RFC 2119 解释。这份正文没有加上后来常见的「只在全大写时才算」。下文的「必须」对应所引原文的大写词。
同一条消息里只能有一个 OPT。查询里若多于一个,必须回 FORMERR(RCODE=1)。OPT 不携带 DNS 数据,只携带这一次问答的控制信息。它必须不被缓存、不被转发,也不得从主文件存取。它可以出现在附加区的任何位置;若同时有 TSIG 或 SIG(0),那两条仍须留在附加区的最后。
表里另外两列不要和 CLASS 合成一个数:
| 字段 | 第 6.1.2 节写的是什么 |
|---|---|
| CLASS | 请求方的 UDP 载荷大小 |
| TTL | 扩展 RCODE 和标志,不是缓存秒数 |
| RDLEN | 全部 RDATA 的长度 |
| OPTION-LENGTH | 单个选项的 OPTION-DATA 有多少八位组 |
TTL 的高 8 位是扩展 RCODE,接着是 VERSION,再是 DO 位和其余必须由发送方置 0、接收方忽略的 Z,除非后来的规范改了 Z。完全符合本文的版本号是 0。这些位不是载荷大小。
EDNS 是逐跳扩展。使用与否在解析过程的每一对主机之间分别协商,例如存根解析器与递归解析器,或递归解析器与权威服务器(第 1 节)。隧道是否接通,不代替这一对主机有没有放上 OPT。
小于 512 必须当成 512
一个可独立引用的定义句:请求方的 UDP 载荷大小是请求方网络栈能够重组并交付的最大 UDP 载荷的八位组数。路径 MTU 可以比它更小。低于 512 的值必须当成等于 512(RFC 6891 第 6.2.3 节)。
第 6.2.5 节把「小于 512 字节必须当成等于 512 字节」又写了一次。没有 EDNS 时,UDP 上的 DNS 消息以 512 八位组为限,第 4.3 节把这句归于 RFC 1035。2026 年 10 月 25 日没有重读 RFC 1035,因此不另引那一份的措辞。
请求方应当填入自己确实能够接收的值。原文的例子是:若防火墙会丢掉分片后的 IP 包,请求方就不应当选一个会引起分片的值。512 八位组的 UDP 载荷需要 576 八位组的 IP 重组缓冲。在以太网的 IPv4 或 IPv6 上,在 1280 与 1410 字节之间选择「是合理的」。不担心分片时,实现者应当考虑更大的值。没有关于目的服务器的既有知识时,实现应当用自己配置或实现过的最大值当起点。
第 6.2.5 节另有一组建议,力度不同:由于事务开销,不推荐把体系结构上的极限当成最大 UDP 载荷大小。即使协议栈能重组 64 KB,一个可取的折中可以是以 4096 八位组为起点。回退应当从较大的尺寸开始,例如 4096;失败后再试 1280 到 1410 附近;再失败时,请求方可以选择 512 字节,大应答随后可能改走 TCP。4096 是这节里的例子,不是 2026 年 10 月对某一解析器的测量。
请求方的最大载荷大小会随时间变化。它必须不得被缓存到广告它的那一次事务之外(第 6.2.3 节)。这和「OPT 记录必须不被缓存」是同一方向的约束,写在不同节。
这个数不是路径能装下的长度
第 6.2.3 节已经写明,路径 MTU 可以更小。链路能转发的最大 IP 包,见 VPN 的 MTU。分组层用确认试包长,见 路径 MTU 探包。CLASS 里的数不代替那两次测量。
EDNS 要广告更大的应答能力,以便少把 UDP 应答截断后再改走 TCP(第 4.3 节)。截断仍是 DNS 头里的另一位,见 DNS 截断位。第 7 节写明,使用 TC 位的截断应答也必须带上最小的应答:DNS 头、问题区和一个 OPT。看见 TC,因此不表示报文里没有 OPT。
符合规范的中间盒必须不得把 UDP 上的 DNS 消息限制在 512 字节。只负责把请求转到递归解析器的中间盒,必须不得修改、也必须不得删除任一方向上的 OPT 内容(第 6.2.6 节)。另有功能的中间盒应当能处理 OPT。若报文特征不同,它们必须把进入的请求和发出的请求当成彼此分开的事务。更细的讨论指向 RFC 5625。2026 年 10 月 25 日没有重读那一份。
DNSSEC 用 EDNS 的标志位请求在应答里带上 DNSSEC 数据(第 3 节)。签名校验失败是另一件事,见 DNSSEC。本文不把 CLASS 里的大小写成签名是否有效。
隧道在外面多了一层头,并不改写已经放进 CLASS 的那个整数。某一客户端或解析器会不会在封装时另改这个字段,本文没有测量。
应答里的 CLASS,正文仍写请求方
第 6.2.4 节讨论应答方的最大载荷大小可以随时间变化,并可以在相距很近的两次事务之间保持不变,例如先用一次任意查询探出这个大小,紧接着的 UPDATE 再用它。这些句子没有写:应答方要把自己的上限填进应答 OPT 的 CLASS。
勘误 8348 的状态是 Held for Document Update,类型是 Technical,2025 年 7 月 1 日被挂起。它建议把第 6.1.2 节表里的「请求方的 UDP 载荷大小」改成「发送方的 UDP 载荷大小」,并说明这是恢复 RFC 2671 的用词。笔记认为,按已发表的字面,应答方会把请求方的大小抄进应答,从而没有位置放下应答方自己的上限。本文不把这条尚未入正文的勘误当成现行规则,也没有重读 RFC 2671 去核对那份旧表。已发表的定义仍以第 6.1.2 节和第 6.2.3 节为准。
同日勘误页上,已验证的 3604 是编辑性的,改第 9.1 节选项代码分配,不改 CLASS。被拒绝的 6982 涉及第 4.3 节。本文不采用被拒绝的文本。
EDNS 客户端子网 和 DNS Cookie 都放在 RDATA 的选项里。它们的长度是 OPTION-LENGTH。名字压缩是域名的另一套编码,见 DNS 名字压缩。三者都不是 OPT 固定部分里的这个 CLASS。
第 8 节写明,宣布很大的 UDP 缓冲可能让中间盒丢掉 DNS 消息,宣布过小则可能退回 TCP。本文只记录这个后果,不提供构造过大请求或迫使退回的步骤。
现象对照
| 现象 | 更可能先看什么 |
|---|---|
| 附加区有一条类型 41,CLASS 不是 1 | 按第 6.1.2 节,这是载荷大小,不是地址类 |
| CLASS 小于 512 | 必须当成 512。第 6.2.3 节和第 6.2.5 节各写了一次 |
| CLASS 很大,路径上大应答仍丢失 | 第 6.2.3 节:路径 MTU 可以更小。第 8 节还写了中间盒丢弃 |
| 应答带 TC,同时也有 OPT | 符合第 7 节。截断应答仍须带上 OPT |
| 应答 CLASS 与查询 CLASS 相同 | 已发表正文没有把应答 CLASS 定义成应答方自己的上限。勘误 8348 尚未入正文 |
| 同一条消息里两个 OPT | 查询必须回 FORMERR |
核对清单
- CLASS 是请求方的 UDP 载荷大小:类型 41,NAME 必须为 0。RDLEN 和 OPTION-LENGTH 是另外两个长度;
- 小于 512 必须当成 512:这句出现两次。4096 和 1280–1410 是建议里的例子,不是一次测量;
- 不得缓存到这次事务之外:OPT 本身也必须不被缓存。路径 MTU 可以更小;
- 应答 CLASS 不要补写:第 6.2.4 节没有把应答方的上限放进 CLASS。勘误 8348 是 Held;
- 它不是客户端子网、Cookie 或截断位。RFC 1035、RFC 2671 和 RFC 5625 没有重读。