摘要

  • RFC 10029 保留一个 DNS 主问题,再通过 EDNS 请求额外 QTYPE;响应选项只列出那些与主回答共享 RCODE 和相关标志、并且已被完整处理的额外类型。
  • 同包到达不构成跨类型原子快照。未列出的类型必须另发查询;已返回的 RRset 仍可能来自不同区域、签名者、TTL 时点与缓存历史,应用是否采用还要单独证明。

最危险的误判不是解析失败,而是解析“成功”。客户端需要 A、AAAA 和 HTTPS。它把 A 放在主问题中,另外请求 AAAA 与 HTTPS。递归解析器返回 NOERROR,包里有 A,MQTYPE-Response 只列出 AAAA。业务代码看到地址后立即连接,遥测则把整个动作标成一次完整查询。

HTTPS 没被列出,原因可能完全不同:缓存里暂时没有;单独查询会得到不同的 RCODE 或权威标志;解析器达到了工作预算;完整记录塞不进响应。单凭遗漏,谁也不能确定是哪一种。

报文完成了,决策所需的证据没有完成。

RFC 10029 于 2026 年 7 月作为标准轨文档发布,解决的是一个明确的线路效率问题:应用经常同时需要多个相互关联的 DNS 类型,却不能在普通 QUERY 中简单堆放多个问题。RFC 9619 已消除旧有歧义:QUERY 的 QDCOUNT 不得大于一,否则按格式错误处理。

因此,新机制没有把多个问题伪装成一个问题。它保留主 (QNAME, QCLASS, QTYPE),把额外的数据类型写进 EDNS 选项。主问题继续决定公共响应头,其他类型逐个接受可合并性检查。

请求清单只是愿望,响应清单才是收据

客户端用 MQTYPE-Query 请求额外类型,选项代码为 20;服务器用不同的 MQTYPE-Response 返回已完成类型,代码为 21。当前 IANA DNS 参数登记表 将两者列为可选项,并以 RFC 10029 为依据。

区分两个代码不是装饰。某些中间设备会原样回显 EDNS 选项;如果请求与响应共用一个标识,回显可能被误判成服务器给出的完成证明。现在,只有主问题加上响应选项中的类型列表,才构成本包完整回答范围。

空的响应列表也有意义:服务器理解扩展,但没有完成任何额外类型。响应选项完全缺失、错误回传查询选项、类型重复,或者返回 FORMERR,则客户端必须把扩展视为不受支持或无效,并对仍然需要的类型发起普通查询。

这也不是 ANY 的替代名。RFC 8482 允许 ANY 返回最小内容,甚至由服务器选择一个 RRset。RFC 10029 不承诺“给我全部”;它承诺清楚标出“这一次完整给了哪些类型”。

一个响应头不能同时讲两套事实

服务器先构造主类型回答,并在此时确定 RCODE、AA、AD、TC 等公共状态。如果主回答已经需要截断,就不再为合包处理额外类型。

随后,每个额外 QTYPE 按照其单独查询结果接受判断。它只有在 RCODE 与相关标志同主回答一致时才能合入。主类型是 NOERROR、额外类型是 SERVFAIL,不能共享同一个成功码;父区一侧的 DS 回答具有权威性,而同处父区的 NS 数据可能不具有相同 AA,也不能强行共用一个头部。

RFC 的这个区切例子揭示了实质:少发一个包,不值得以抹掉权威差异为代价。RFC 2181 所说明的数据可信级别仍然有效,但相同级别不等于相同组织、相同发布行为或相同证明链。

“没有截断”不代表“全部满足”

对一个额外类型而言,纳入必须是完整的。服务器把 RR 放进它们在独立回答中本应出现的区段,并在同一区段去除重复项。只有该类型需要的完整 RRset 与证明材料都能放入,才把类型写入响应清单。

如果受响应大小或资源限制,服务器省略这个类型,而不是为了额外内容主动制造截断。因此,一个 TC=0 的包仍可能没有覆盖客户端最初请求的全部类型。TC 说明最终包是否截断,不说明业务证据是否齐全。

RFC 6891 还提醒我们,OPT 记录本身不进入缓存,声明的 UDP 负载大小属于这一次交易,且不保证实际路径能承载。防火墙可能丢弃分片,中间设备也可能影响选项。规范要求合规设备正确转发,不等于每条现实路径都已经合规。能力证据必须按解析路径和尝试保存。

遗漏故意不等于否定

RFC 10029 列出几类可能原因:递归缓存没有该类型;该类型独立结果的 RCODE 或标志不一致;服务器不愿继续或达到工作上限;响应尺寸不足。协议没有在遗漏本身中编码唯一原因。

所以,HTTPS 不在清单中,不能推出 HTTPS 记录不存在。它不是 RFC 2308 意义上的完整否定回答,也没有自动携带 RFC 4035 要求的 DNSSEC 否定证明。它同样不能单独证明策略拒绝、故障或攻击。

只要应用仍需要该类型,客户端就必须发起独立查询。这个回退不是性能补丁,而是正确性边界:传输优化不得替应用删减必要证据。

同时送达,不等于同时产生

RFC 10029 明确指出,包里的记录可能来自不同 DNS 区域,不存在性证明也可能由不同签名者生成。各 RRset 的 TTL 可以不同,进入递归缓存的时间也可以不同。A 可能来自早先缓存,AAAA 刚刚刷新,HTTPS 则是即时查回。同包交付不会把三个时钟重置成同一发布时点。

RFC 9499 提供了必须保留的精确术语:RRset、权威服务器、递归解析器、缓存与验证结果不是一个笼统“DNS 成功”的不同写法。证据模型应按类型保存来源,而不是只记一个包 ID。

即使 HTTPS RRset 已完整返回,应用决策仍未结束。RFC 9460 要求客户端处理优先级、必需参数、地址与可用性。拿到记录不等于理解记录,更不等于选择它或连接成功。

建立类型完整性账本

每次尝试至少保存:QNAME、QCLASS、主 QTYPE、额外请求类型的有序列表、解析器与路径、EDNS 声明大小、响应选项是否存在及其精确类型清单、RCODE、AA、AD、TC,以及请求集合与完成集合之间的差集。

每个返回类型还要保存完整 RRset、否定证明、来源区域、权威状态、签名者、DNSSEC 验证、TTL、缓存或网络来源与观察时间。随后把每次独立回退、应用选择的地址或服务记录、最终连接结果绑定到同一应用请求。

这样可以把四个状态分开:包已收到、QTYPE 已完整回答、RRset 已验证、应用需求已满足。

Heng Lu 的运行代码优先原则要求把文档与部署事实分开:标准发布和 IANA 登记证明规则存在,不证明某条路径支持它。他提出的最小初始规范、本地未来决策与自愿采用正适合这一扩展:公共格式必须狭窄且可确定验证,类型数量和资源预算由运营者本地决定,普通查询保留为兼容与退出路径。他关于现实而非倡议才是产品的立场则界定报道语言:登记表说明可能性,真实包、完成清单、验证与应用结果才说明现实。

同一个信封可以承载多份证据,却不能把多份证据变成同一个权威事实。