摘要

  • RFC 2360 是面向互联网标准作者的 BCP 22,不是一项协议。它的目标只是提高独立实现互通的可能性,并明确承认清晰文字不能保证互通。
  • 文档最重要的要求落在异常分支:畸形输入应部分接收还是整体拒绝,丢弃或报错会怎样改变连接与邻接状态,关键资源或规模上限被突破后各实现应如何作出一致反应。
  • 报文图、规范词、形式语法、汇总表与状态机各自解决不同问题。它们都不能代替运行代码和互操作观察。

长度字段结束了,决定才刚开始

一张报文图看起来像协议最坚硬的部分。字段宽度、网络字节序、标志位与长度都可以精确到每一位。只要发送者和接收者照图实现,互通似乎就是剩下的工程问题。

RFC 2360 从图的边缘提出了更难的问题:如果计数说后面有三个条目,消息却还剩下像第四个条目的字节,接收者该怎么办?忽略尾部、把它当成额外路由,还是把整条更新判为可疑?三种实现都可能正确读出前三个条目,却把网络带进不同现实。

Gregor D. Scott 编辑的这份文档于 1998 年 6 月成为 BCP 22,题为《互联网标准作者指南》。它整理成功与失败的规范经验,但没有列出一份可供后人随意补写的事故名单。文章能确认的是方法:含糊规范会阻碍互通,清晰规范能提高互通概率,却不会自动生成一致实现。

这个克制决定了它的历史价值。标准组织能够公开共同声明,不能替每个实现执行分支,也不能把实验室通过写成生产结果。真正容易分叉的地方,往往不是理想消息,而是输入越界、定时器到期和资源不足之后的下一步。

“丢弃”不是一个完整动作

RFC 2360 要求说明偏离或超出规范的行为。原因并不抽象:实现者常在这里选择不同答案。丢弃与调用错误处理都是可能方案,关键在于文档必须选定边界并写明后果。

同样是丢弃一个帧,可以把它视为从未到达,让现有定时器继续;也可以认为对端已经失去同步,重置连接或邻接。两者都没有把坏数据交给上层,却改变了不同状态。只写“无效报文 MUST 丢弃”,仍然没有告诉实现者丢弃之后谁还活着。

资源边界同样属于协议。队列满、内存不足、标识符耗尽或并发量超过设计值时,是拒绝新工作、牺牲旧状态、向对端返回错误,还是沉默?如果每个产品都选择自己的生存方式,局部资源压力就会变成跨节点状态不一致。

这也是文档谨慎对待“发送要保守,接收要宽容”的原因。宽容不是让每个接收者自行猜测。作者应分别规定发送与接收行为,并在尽量利用报文内容与启动错误程序之间划线。对路由协议而言,接受有歧义的信息可能比丢掉一条更新更危险。

状态机补上报文图没有画出的时间

报文图回答“哪里”。状态机回答“什么时候、在什么记忆之下、发生什么”。RFC 2360 建议列出状态、变量、事件、转移与动作,也要求动作有先后关系时写出顺序。

同一条消息在初始状态可能合法,在关闭状态可能是非法转移。相同超时在等待确认时可能触发重试,在已关闭时应被忽略。若两个动作颠倒顺序,对端可能看见完全不同的中间状态。

不过,文档没有把状态图神化。图、表和时间线只是正文的辅助;发生冲突时,详细文字优先。这又产生一项编辑责任:当同一要求出现多种说明时,必须指出哪一种具有约束力。

汇总表承担另一项工作。长文档容易漏掉某个 MUST、OPTIONAL 或禁止项,表格可以把功能、章节与要求级别对应起来。它减少遗漏,不证明符合性。

大写词不能替缺失的行为作决定

RFC 2119 已经提供 MUST、SHOULD、MAY 等要求词。RFC 2360 要求作者尊重这些词的既定含义,因为它们用于标明互通要求或限制有害行为。

但“MUST 拒绝”仍然缺少许多坐标:拒绝的是字段、消息还是整个会话?认证之前还是之后?是否回复错误?序列号是否消耗?已建立状态是否保留?词的力度不能补出不存在的状态模型。

形式语法也有边界。它可以定义哪些字符串合法,却不能单独说明合法命令由谁授权、将造成什么效果,也不能决定资源失败后的恢复。RFC 2360 甚至提醒,机器可解析的记法可能很难被人理解,不能取代清楚的协议说明。

“可选”只是把决定移到了运行时

可选功能常用来容纳差异。RFC 2360 追问差异相遇时会怎样。每个选项应服务真实需求,有明确默认值,说明使用与不使用的后果,也要检查互斥组合。一个实现省略选项,不应因此无法与合规的基本实现互通。

把功能命名为 OPTIONAL,并没有消除决定。双方仍需发现能力、同意使用条件,并知道回退损失。安全相关功能若默认关闭,便利可能无声地替代原本的保护。后来 RFC 6709 对扩展风险进行了更细分析;它适合用于比较,不能被写成 RFC 2360 直接导致的结果。

为什么要留下“为什么”

指南还要求变更记录、版本差异与决策历史。其目的不是把旧共识永远冻结,而是防止原参与者离开后,只剩结果、不见理由。

未来维护者可能发现一条规则麻烦,却不知道它曾隔开哪种失败。一个更简单的捷径会显得等价,因为产生分歧的条件已从日常测试中消失。保留理由,才能让后人以新证据修正规则,而不是凭遗忘推翻它。

安全、管理、规模、网络稳定性、国际化与 IANA 也不是尾部装饰。它们迫使作者公开协议依赖的外部权力与边界:谁分配号码,什么拓扑会难以收敛,资源上限是什么,运营者能观察什么,全球用户会在哪个字符或语言假设上被排除。

规范仍只是现实的一层

Lu Heng 对运行代码优先与现实分层的讨论,为 RFC 2360 的限制提供了清楚框架。规范陈述应有行为;代码表明某个实现做了什么;互操作测试记录特定版本在特定用例下是否一致;生产观察才说明真实负载与敌对输入下发生了什么。

完整状态表不证明代码执行了它。正常路径全绿,不证明内存耗尽时仍收敛。两个产品彼此互通,不证明它们符合文本。一次部署没有崩溃,也不证明所有选项组合安全。

最小共同层因此不能只有语法。它必须足够小,让独立团队可以实现与测试;也要足够明确,能决定会影响共享状态的异常分支。RFC 2360 记录的历史转折正是这一点:协议不仅是发出去的位,也是理想条件消失之后必须共同承担的下一步。

来源与边界

出版状态与主要指南来自 RFC 2360 记录和 RFC 2360 正文。标准流程背景见 RFC 2026,规范词见 RFC 2119,架构背景见 RFC 1958,当时的作者说明见 RFC 2223。指南举例涉及 RFC 1122与 RFC 2328;RFC 6709只提供后来的扩展设计对照。证据边界采用 Lu Heng 关于运行代码优先、最小初始规范与现实分层的论述。这些来源不提供当前符合率,不证明每条建议背后都有某次具名事故,也不保证后来的 RFC 全部遵循指南。