摘要

  • 两份文件的分量不同:RFC 5625 是单人署名的「最佳现行做法」,其最硬的义务几乎都在禁止中间设备破坏它看不懂的报文;RFC 8490 是六人署名的「建议标准」,其禁令在构造一个共享会话状态。两者都不约束选择不实施的人。
  • 国际互联网号码分配机构的 DNS 参数登记表中,操作码值 6 对应「DNS Stateful Operations」,并附有 RFC 8490 的引用,另有 DSO 类型码表列出 KeepAlive、RetryDelay、EncryptionPadding。这份登记条目是整份材料里唯一不依赖任何人持续配合就能存续的东西,而它并不说明哪台机器在用。

先看登记表,因为它最不煽情

在国际互联网号码分配机构的 DNS 参数登记表中,操作码表把数值 6 分配给「DNS Stateful Operations (DSO)」,并注明依据 RFC 8490;紧邻的类型码表固定了 0x0001 KeepAlive、0x0002 RetryDelay 与 0x0003 EncryptionPadding。

登记表的一个条目是特定形态的公共行为。它不随作者是否继续参与而变化,不因作者离职而失效,也不需要任何人同意才能留在名册上。但它同样不意味着人们通常以为的那件事:条目记录的是一个标识存在、叫什么名字、由谁定义,它对哪款软件会发送这个标识保持沉默。

这条从名册到机器的距离,就是本文的全部论点。贝利斯的材料之所以格外清楚,是因为同一位工程师出现在两份以相反方式失败的文件里。

一份文件,一个作者,一句请求讨论

RFC 5625《DNS 代理实施指南》于 2009 年 8 月作为 BCP 152 发布(RFC 5625 信息页)。BCP 152 子系列页显示,该子系列只包含一份 RFC。作者署名一栏只有一个人:任职于 Nominet UK 的 R. Bellis(RFC 5625 正文)。

它的状态说明非常坦白地交代了这是一句什么性质的话:该文件「specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements」。整句话就是全部的约束机制。最佳现行做法并不附带任何一致性认证计划、任何发证机构、任何一旦失败就使产品失效的测试套件。它是一份经过斟酌的社群意见,交给可以不同意的人。

最硬的动词几乎都在禁止插手

读一遍带强制力的句子,规律立刻显现。RFC 5625 用最强的措辞保护代理本身并不理解的流量:

  • 第 4.1 节:代理 MUST 忽略任何未知的 DNS 标志位,并按原样转发这些报文。
  • 第 4.4 节:如果代理必须自行截断响应,它 MUST 置位 TC 比特。
  • 第 4.5 节:DNS 代理 MUST 具备转发包含 TKEY 资源记录报文的能力。

这三条义务都是对干涉的禁止。文件从未命令某个网关去实现新功能,只是禁止它毁掉并不属于它的语义。积极的抱负写得明显更软:第 3 节说,建议代理尽可能保持透明;第 4.4.1 节说,收到 TCP 请求时应以 TCP 转发,不要先试一次 UDP;第 5.2 节建议所描述选项的默认值为空。透明是建议,别把人家的东西弄坏是义务。

这不是畏缩。家用网关的固件停止更新的时间,远比 DNS 停止变化的时间来得早。作者无法预知未来的扩展会向这台设备提出什么要求,于是唯一站得住的规则就变成他写下的那条:把你不懂的东西原样带过去,在你必须截断的时候老实说明。

六位署名,和会构建出东西的义务

RFC 8490《DNS Stateful Operations》是 2019 年 3 月的建议标准,更新了 RFC 1035 与 RFC 7766(RFC 8490 信息页)。署名共有六位:ISC 的 R. Bellis、Apple 的 S. Cheshire、Sinodun 的 J. Dickinson 与 S. Dickinson、Nibbhaya Consulting 的 T. Lemon,以及无隶属的 T. Pusateri(RFC 8490 正文)。

它的状态说明采用标准轨道的固定措辞:文件代表 IETF 社群的共识,已经过公开评议,并由互联网工程指导组批准发布。它行使的权威是从一个内部设有评审者的流程里借来的,并非作者的自行宣告。

而它的强制句在结构上做了与 RFC 5625 完全不同的事。它不只是阻止中间设备碍事,而是从两个端点制造出一个共享的对象:

  • 第 5.1 节:在 DSO 会话被双向建立之前,服务器 MUST NOT 发起 DSO 请求报文或单向报文。
  • 第 5.1.1 节:实施 DSO 的服务器 MUST NOT 对 Keepalive 请求返回 DSOTYPENI,因为 Keepalive 的 TLV 是强制实施的。
  • 第 5.4.1 节:若收到的 DSO 响应报文中 MESSAGE ID 为零,属致命错误,接收方 MUST 立即强制中断连接。

连着读这三句,它们描述的是一个由两方构成的制度。会话只能通过双向建立存在。一个有名有姓的拒绝码,因为另一件东西是强制实施的而对某一类请求变得不可用。一个畸形的标识不是警告而是切断。两台机器此后共同持有一份任何一方都无法单方面宣布成立的状态,而文件正是这种共同性被写下来的地方。

禁令之外,起草者留下了裁量,并且标出了裁量。收不到响应时,客户端 SHOULD 等待 30 秒;若服务器断开连接,客户端 SHOULD 把该服务实例标记为不支持 DSO。这些是关于如何解读沉默的指示,与关于如何构成会话的规则不属于同一类。

这份材料没有解决的三件事

有三个自然会追问的问题,在本文所审阅的材料里没有答案,值得说明确切的理由。

第一是更正记录。在 2026 年 10 月 18 日查阅时,RFC 5625 与 RFC 8490 的勘误页都没有显示任何条目,两份信息页也没有指出废止或后继文件。空白的勘误页是弱信号:它可能意味着文本经受住了时间,也可能意味着还没有人提交更正——这是两件不同的事实,从外面看却一模一样。

第二是产生记录。两篇 RFC 在RFC 5625 的草案跟踪记录与RFC 8490 的草案跟踪记录里的记录,在此处只能以页面摘要的形式获得,而不是完整的修订历史,因此哪一版草案改动了哪一句话、哪一次评审先于哪一版修订,只部分可见。工作组脉络是清楚的:代理指南出自 DNSEXT,带状态操作出自 DNSOP,但逐句的编辑史并不清楚。

第三,也最重要:两份文件都没有取得任何实施证据。因此本文不主张 RFC 5625 改变了网关转发查询的方式,也不主张 DSO 出现在任何出货的解析器中。这些是关于软件的经验问题,而软件在所审阅的材料里没有留下痕迹。

作者权限真正结束的地方

面对像贝利斯这样的工程师,最容易犯的错误是把 RFC 编号读成网络的证据。它不是。编号记录的是一份文件被发布、被评审、被编目;它对哪些机器运行文件所描述的东西一言不发。合规出现在部署里,而部署是别人的决定。

他能确凿控制的,范围更窄,也更有意思。他控制措辞:哪一项义务成为 MUST,哪一项留在 RECOMMENDED,以及在 RFC 5625 里尤其是——文件最硬的动词是拿去禁止破坏,还是拿去索取功能。他与五位合著者一起,控制着把会话建立写成前置条件而非礼貌的选择。这些都是真实的行为,可以归到具名的人头上,也可以在文本里看见。

他不能控制的,是决定这一切是否重要的那一部分。实施者可以读完 RFC 8490,把会话状态的成本与固件排期放在一起权衡,然后拒绝。文件里的任何一句话都触不到他。登记表照样保留那个编号——正因如此,登记表作为持久性的证人,比正文作为采纳的证人要可靠得多。