摘要

  • RFC 3479 为受保护的 LDP 操作配置会话内序列号,并用累积 ACK 标出接收方已经持久保存的共同前沿。
  • 重连只重放前沿之后的未知尾部;检查点刷新确认边界,而受控停机需要 Cork 三次交换才能让两个方向同时静止。

一条可靠的 TCP 流替 LDP 隐藏了许多麻烦。只要字节流连续,两个对端就可以相信标签操作按序抵达;但控制面切换令连接突然消失时,新连接无法回答旧消息究竟停在哪里。它可能已经越过网络,可能已经进入对端内存,也可能已经处理成状态却尚未落入可恢复存储。RFC 3479 把这段模糊地带变成了一次账本对账。

第一步不是发送 ACK,而是确定哪些操作有资格进入账本。初始化消息中的 FT Session TLV 用 S 位开启逐操作的序列号保护,A 位可以要求全部标签都受这种保护,C 位选择检查点机制,而且 C 可以在 S 未开启时单独使用。不同组合定义了不同的可恢复集合。若不先记录协商结果,同一个“检查点”一词可能指向完全不同的消息范围。

对于 Sequence Numbered FT Label,发送方在相关 LDP 消息中加入 FT Protection TLV,并递增这条会话自己的序列号。接收方不能在看见消息时立即把它算作已确认;它必须先把整条消息,或由处理消息得到的状态,保存到故障后仍可恢复的位置,然后才能返回 FT ACK。规范允许实现保存不同形态,却不允许把短暂接收冒充持久事实。

ACK 是累积的。确认序号四意味着一至四构成了已保存前缀,不意味着五以后也安全。确认可以延迟并合并,重复 ACK 可以接受,乱序 ACK 则会破坏“前缀”的含义。当未确认序号耗尽时,新的受保护操作甚至无法取得序号。由此可见,ACK 既减少往返,也制造了一项需要监控的欠账。

真正的对账发生在 TCP 重连之后。双方在新的初始化交换里说明自己保存到哪个序号。发送方把超出对端确认前沿的受保护消息重新发出,接收方按首次收到来处理。新会话没有复原旧 TCP 字节流;它只利用两份持久记录,重建命运不明的操作尾部。

RFC 3479 允许两类精确的“净零”折叠:Label Request 与对应的 Label Abort 可以相消,Label Mapping 与对应的 Label Withdraw 也可以相消。可是本地队列里出现一正一反,并不足以立即删除它们。如果其中一半已在故障前抵达对端,盲目相消就会留下单边状态。只有从对端 ACK 得知接收边界后,发送方才知道哪些组合确实不必重放。

地址消息也要进入受保护历史,因为 Address 与 Address Withdraw 若在断点两侧分离,两个对端会对地址有效性产生不同判断。恢复后发现旧地址已经失效,就必须明确补发 Withdraw。若双方没有同时声明保存状态,旧地址被视为全部撤回,再按新会话重新广告。

检查点改变的是确认粒度。带 FT Protection TLV 的 Keepalive 要求对端先保存此前所有 check-pointable 消息,再刷新 ACK。若只协商 C 而没有 S,普通消息本身不携带活动序列号,检查点一次覆盖它们的集合;若 S 已开启,检查点覆盖逐序列号保护的标签操作与地址消息。检查点并非天然的“全系统快照”,其边界由协商位决定。

单向检查点仍只证明一个方向。受控停机时,提出停机的一方还必须确认自己已保存对端发送的全部状态。因此 FT Cork TLV 触发三次交换:一方要求静止;另一方处理并保存先前未确认的工作,同时停止产生新的标签和地址操作;最后一条消息闭合反方向的确认。少一跳,就不能说两本账停在同一页。

协议也规定了何时放弃恢复叙事。无法保存状态或挂起操作的对端必须把 FT Reconnect Flag 清零。任何一方清零,双方都应释放旧会话状态。若标签空间边界等会话参数发生变化,旧操作可能已经失去原有合法含义,也不能直接续用。

IESG Note 必须留在历史正文里。它明确警告:这套 TCP 故障切换缺乏足够的计时器与重试值指导,可能发生过早切换,不应成为未来 TCP 容错设计的通用范本。RFC 3479 给出了对账语法,没有给出任何环境都安全的参数答案。

这也划清了与既有文章的范围。RFC 3478 文章讨论陈旧转发状态如何在计时器内借来生存时间;RFC 3612 文章讨论保存状态和对端确认为什么不能证明转发正确。本文只拥有操作日志机制:保护范围、序列流、持久前沿、重发、净零折叠、检查点刷新与双向静止。

按照 Heng Lu 的现实分层,审计应从旧、新会话身份开始,保存 S、A、C、R 位与全部参数。然后为两个对端分别重建已发送序列、已持久保存序列和真正发出的 ACK。在故障瞬间冻结未确认、未保存与挂起队列;在重连后为每一次重发与每一个被折叠的净零组合提供依据;受控停机则保存 Cork 三次消息及双方停止新增操作的时刻。

这样的记录阻止了几个诱人的误报。一个 ACK 不覆盖更大的序号;一个检查点不自动覆盖协商范围之外的消息;一次 Cork 请求不等于双向静止;这些控制凭证也不说明应用是否收到了数据。它们只回答一个更基础的问题:两个对端能够证明共同拥有哪一段操作历史。

RFC 3479 的历史意义正在这里。它没有把故障恢复写成“忘掉以后继续”,而是把它写成两份不完整记忆之间的核对。序列号限定争议,ACK 找到共同过去,重放补回不确定尾部,Cork 握手把双方停在同一边界。TCP 会话断了,操作账本必须重新对账。

来源