1. 简介
IETF 已经指定了使用 UDP、流控制传输协议 (Stream Control Transmission Protocol, SCTP) 和数据报拥塞控制协议 (Datagram Congestion Control Protocol, DCCP) 的数据报传输, 以及分层在这些传输协议之上的协议 (例如 SCTP/UDP、DCCP/UDP、QUIC/UDP) 和直接运行在 IP 网络层之上的数据报传输. 本文档描述了一种健壮的路径 MTU 发现 (Path MTU Discovery, PMTUD) 方法, 可与这些传输协议 (或使用其传输服务的应用) 一起使用, 以发现在一条 Internet 路径上使用的合适包尺寸.
1.1. 经典路径 MTU 发现
经典路径最大传输单元发现 (Classical Path Maximum Transmission Unit Discovery, PMTUD) 可用于任何能够处理 ICMP Packet Too Big (PTB) 消息的传输 (例如 [RFC1191] 和 [RFC8201]). 在本文档中, 术语 PTB 消息同时指携带 Fragmentation Needed (类型 3, 代码 4) 错误的 IPv4 ICMP Unreachable 消息 (类型 3) [RFC0792], 以及 ICMPv6 Packet Too Big 消息 (类型 2) [RFC4443]. 当发送方收到 PTB 消息时, 它会将有效 MTU 降低为 PTB 消息中作为链路 MTU 报告的值. 经典 PMTUD 规定了一种周期性增大包尺寸的方法, 以尝试发现所支持 PMTU 的提升. 以大于当前有效 PMTU 的尺寸发送的包被称为探测包 (probe packet).
非探测用途的包要么被分片到当前有效 PMTU, 要么发送尝试因错误码而失败. 可以为应用提供一个原语, 让它们读取最大包尺寸 (Maximum Packet Size, MPS), 该值由当前有效 PMTU 推导得出.
经典 PMTUD 存在协议失效的可能. 一种失效情形是: 使用大于实际 PMTU 的包尺寸的流量被黑洞化 (所有大于实际 PMTU 的数据报都被丢弃). 当 PTB 消息因某种原因未被回送到发送方时, 就可能出现这种情况 (例如参见 [RFC2923]).
PTB 消息未被交付的例子包括以下几种:
-
ICMP 消息的生成通常受到速率限制. 这可能导致没有 PTB 消息被生成并发送给发送方 (参见 [RFC4443] 第 2.4 节).
-
ICMP 消息可能被包括防火墙在内的中间件过滤 [RFC4890]. 防火墙可能被配置了阻止入站 ICMP 消息的策略, 这会使位于该防火墙之后的发送端点无法接收 PTB 消息.
-
当发出 ICMP 消息的路由器丢弃一个隧道化的包时, 产生的 ICMP 消息会被定向到隧道入口. 该隧道端点负责转发 ICMP 消息, 处理 payload 字段中被引用的包 (quoted packet) 以消除隧道的影响, 并将格式正确的 ICMP 消息返回给发送方 [TUNNELS]. 若未做到这一点, PTB 消息将无法到达原始发送方.
-
转发的非对称性可能导致不存在回到原始发送方的返回路由, 从而阻止 ICMP 消息被交付给发送方. 当使用基于策略的路由或等价多路径 (Equal-Cost Multipath, ECMP) 路由, 或当中间件充当应用负载均衡器时, 也可能出现此问题. 一个例子是 ECMP 路由器基于 IP payload 中的字节选择通往服务器的路径. 在这种情况下, 如果服务器发送的包在经过 ECMP 路由器之后遇到问题, 则 ECMP 路由器需要将产生的任何 ICMP 消息定向回原始发送方.
-
还存在其他因为包尺寸而导致下一跳目的地无法接收包的情况. 这可能是由于节点之间二层路径的配置错误, 例如二层交换机中配置的 MTU, 或最大接收单元 (Maximum Receive Unit, MRU) 配置错误. 如果包被链路丢弃, 这将不会导致向原始发送方发送 PTB 消息.
另一种失效可能由不在网络路径上的节点引起: 它发送 PTB 消息, 试图迫使发送方更改有效 PMTU [RFC8201]. 发送方可以利用 PTB 消息 payload 中被引用的包来验证所收到的 PTB 消息确实是针对实际源自该发送方的包而生成的, 从而保护自己不对这类消息作出反应. 然而, 在某些情况下发送方无法完成这种验证.
无法验证 PTB 消息的例子包括以下几种:
-
当发出 ICMP 消息的路由器实现 RFC 792 [RFC0792] 时, 它只被要求在被引用的 payload 中包含该包 IP payload 的前 64 位. 剩余的字节数可能不足以让发送方解读其中引用的传输层信息.
注意: RFC 1812 [RFC1812] 的建议是, IPv4 路由器返回的被引用包应尽可能多地包含原始数据报, 同时 ICMP 数据报长度不超过 576 字节. IPv6 路由器则尽可能多地包含引发消息的包, 同时 ICMPv6 包不超过 1280 字节 [RFC4443].
-
隧道和/或加密的使用会减小返回到原始源地址的被引用包的尺寸, 增加了剩余字节数不足以让发送方解读其中引用的传输层信息的风险.
-
即使 PTB 消息包含了被引用包的足够字节, 网络层也可能缺乏验证该消息所需的上下文, 因为验证依赖于端点节点上活动传输流的信息 (例如正在使用的套接字/地址对以及其他协议头部信息).
-
当包被封装/隧道化到一个加密传输之上时, 隧道/封装入口可能缺乏执行验证所需的上下文或计算能力, 无法重建所需的传输头.
-
当 ICMP 消息由某个向包内插入了头部的网络段中的路由器生成时, 被引用的包可能包含原始发送包中不存在、且 PL 发送方不处理或可能不知道如何处理的额外协议头部信息. 这会破坏发送方验证该 PTB 消息的能力.
-
对包头进行转换的网络地址转换 (Network Address Translation, NAT) 设备也应当转换 ICMP 消息并更新该消息中的 ICMP 引用包 [RFC5508]. 如果未正确转换, 发送方将无法把该消息与发起该包的 PL 关联起来, 因而无法验证这条 ICMP 消息.
1.2. 分包层路径 MTU 发现
术语分包层 (Packetization Layer, PL) 被引入用来描述负责将数据块放入 IP 包 payload 并选择合适 MPS 的层. 这一功能通常由传输协议 (例如 DCCP、RTP、SCTP、QUIC) 执行, 但也可以由工作在传输层之上的其他封装方法执行.
与 PMTUD 不同, 分包层路径 MTU 发现 (Packetization Layer Path MTU Discovery, PLPMTUD) [RFC4821] 引入了一种不依赖 PTB 消息接收与验证的方法. 因此它比经典 PMTUD 更健壮. 这已成为实现 PMTU 发现的推荐方法 [BCP145].
本文档更新 [RFC4821], 规定了面向数据报 PL 的 PLPMTUD 方法; 同时更新 [BCP145], 使其在 UDP 数据报场景下引用本文档规定的方法, 以取代 [RFC4821] 中的方法.
它使用一种通用策略: PL 发送探测包, 以搜索能够通过网络路径发送的最大无分片数据报尺寸. 发送探测包是为了以更大的包尺寸进行探索. 如果探测包被成功交付 (由 PL 判定), 则将 PLPMTU 提升到该成功探测的尺寸. 如果检测到黑洞 (例如 PLPMTU 尺寸的包持续未被收到), 该方法会降低 PLPMTU.
数据报 PLPMTUD 为实现带来了灵活性. 在一个极端, 可以将其配置为只执行黑洞检测与恢复, 与经典 PMTUD 相比具有更高的健壮性. 在另一个极端, 可以禁用所有 PTB 处理, 由 PLPMTUD 取代经典 PMTUD.
PLPMTUD 还可以包含额外的一致性检查, 而不会增加在探测以发现路径 MTU 时数据丢失的风险. 例如, 利用 PL 或更高层可获得的信息, 收到的 PTB 消息能够先经过验证再被使用.
1.3. 面向数据报服务的路径 MTU 发现
本文档的第 5 节给出了一组算法, 供数据报协议发现能够通过网络路径发送的最大无分片数据报尺寸. 该方法依赖第 3 节中描述的 PL 特性, 适用于运行在 IPv4 和 IPv6 之上的传输协议. 它不要求较低层的配合, 尽管当收到的 PTB 消息被提供给 PL 时, 它可以利用这些消息.
UDP 使用指南 [BCP145] 第 3.2 节中的消息尺寸指南指出, "应用应当 (SHOULD) 使用 IP 层提供的路径 MTU 信息, 或实现路径 MTU 发现 (PMTUD)", 但并未提供用于发现在网络路径上可使用的最大无分片数据报尺寸的机制. 本文档更新 RFC 8085, 规定以本文档的方法取代 PLPMTUD [RFC4821], 并提供了一种将所发现的最大尺寸作为 MPS 共享出去的机制 (参见第 4.4 节).
[RFC4821] 第 10.2 节曾为流控制传输协议 (Stream Control Transport Protocol, SCTP) 推荐了一种 PLPMTUD 探测方法. SCTP 使用的探测包由一个最小尺寸的 HEARTBEAT chunk 与 [RFC4820] 中定义的 PAD chunk 捆绑而成. 然而, RFC 4821 并未给出完整的规范. 本文档通过提供完整的规范取代了那一描述.
数据报拥塞控制协议 (DCCP) [RFC4340] 要求实现支持经典 PMTUD, 并规定 DCCP 发送方"必须 (MUST) 为每个活动的 DCCP 会话维护其所允许的 MPS". 它还定义了网络路径所支持的当前拥塞控制 MPS (CCMPS). 该文档建议使用 PMTUD, 并建议使用控制包 (DCCP-Sync) 作为路径探测包, 因为它们不会带来应用数据丢失的风险. 本规范定义的方法可以与 DCCP 一起使用.
第 4 节和第 5 节定义了数据报分包层路径 MTU 发现 (Datagram Packetization Layer Path MTU Discovery, DPLPMTUD) 的协议机制与规范.
第 6 节规定了面向数据报传输的方法, 并提供信息以支持在其他数据报传输以及使用数据报传输的应用中实现 PLPMTUD.
第 6 节还给出了针对 SCTP 端点的建议, 更新 [RFC4960]、[RFC6951] 和 [RFC8261], 使其使用本文档规定的方法取代 [RFC4821] 中的方法.