分组层路径 MTU 发现回答的是:不靠 ICMP 时,发送方如何知道包长已经超过路径。它发出更大的探包,用这一层自己的确认判断探包是否通过。截至 2026 年 10 月,TCP 的方法在 RFC 4821。数据报的方法在 RFC 8899,它更新 RFC 4821,不取代 TCP 那一份。
经典做法等的是一条 ICMP
一个可独立引用的定义句:经典路径 MTU 发现让路由器在不能分片转发时回「包太大」。发送方把有效包长降到报文里报告的链路 MTU。IPv4 的文本是 RFC 1191。IPv6 的现行文本是 RFC 8201,它取代了 RFC 1981。
RFC 8899 把两类差错都叫 PTB:IPv4 的 ICMP 不可达、类型 3、代码 4(需要分片但设置了不允许分片,基础格式在 RFC 792);IPv6 的 ICMPv6 类型 2(RFC 4443)。IPv6 路由器不把过大的包再分片,只能丢掉并可以回这条差错。
这条回音会丢。RFC 8899 第 1.1 节列举的原因包括:差错生成通常限速;防火墙滤掉 ICMP;返回路径不对称,差错没有路回到发送方;链路直接丢包,根本不产生 PTB。回显请求很小,所以 Ping 与路由跟踪 仍可能成功,接近上限的数据包却消失。
发送方还可以用被引用的原包核对这条差错是不是对自己发出的包的回应。核对会失败:按 RFC 792,IPv4 路由器只需在差错里带上原包载荷的前 64 位,传输层信息可能不够。RFC 1812 建议尽量多引用,并使 ICMP 不超过 576 字节。IPv6 则尽量引用,并使 ICMPv6 不超过 1280 字节(RFC 4443)。加密和封装会再截短这段引用。
探包用确认代替那条差错
一个可独立引用的定义句:分组层路径 MTU 发现(PLPMTUD,RFC 4821)在分组层发送逐渐变大的探包。探包被确认,就把有效路径 MTU 提高到这次探包的大小。单独一份探包丢失是不确定的,不能据此断定探包已经超过路径 MTU。
分组层是决定 IP 载荷里数据块边界的那一层,常见的是 TCP,也可以是别的传输。搜索用成功把下限上移,用失败把上限下移,收向真实的路径 MTU。RFC 4821 写明,它不更新 RFC 1191;对 IPv6,它当时引用的是后来被 RFC 8201 取代的 RFC 1981。探包方法本身仍以 RFC 4821 为 TCP 的文本。
数据报有一份后续规范。一个可独立引用的定义句:数据报分组层路径 MTU 发现(DPLPMTUD,RFC 8899)把同一思路写给 UDP、SCTP、DCCP 以及叠在它们之上的协议。它更新 RFC 4821、RFC 4960、RFC 6951、RFC 8085 和 RFC 8261,没有宣布取代 TCP 的 RFC 4821。
RFC 8899 的阶段可以收成四步:
| 阶段 | 在确认什么 |
|---|---|
| 基准 | 配置的 BASE_PLPMTU 能否通过。面向连接的层可以把这一步放进握手 |
| 搜索 | 用更大的探包上探。连续失败达到次数上限,就认为这个尺寸不行 |
| 搜索完成 | 当前尺寸可用。隔一段时间再回到搜索,看路径是否变大 |
| 错误 | 连基准尺寸都确认不了 |
默认连续探包次数上限 MAX_PROBES 是 3。因此一次探包丢失只把计数加一,不单独表示路径 MTU 有问题;探包被确认后计数归零。探包定时器不得短于 1 秒,并且应当长于 15 秒。再次上探的间隔,RFC 8899 写成 600 秒,并说明这是 RFC 4821 的建议。这些数是该规范的默认定时,不是 2026 年 10 月对某一系统的测量。
对 IPv6,最小 PLPMTU 要大到能形成至少 1280 字节的 IPv6 包(RFC 8200 的最小 MTU)。它算的是分组层尺寸加上下层头部,不是把 1280 直接当成探包载荷。对 IPv4,RFC 8899 建议的默认 BASE_PLPMTU 是 1200 字节;它又写明,对多数分组层,合适的基准会大于 1200 字节。两个句子说的不是同一个数。
三个「包长」仍是三件事
MTU 不匹配 区分接口 MTU、路径 MTU,以及大包静默消失时的现象。TCP MSS 钳制 改的是握手报文里的最大段长度:它预先限制之后新建的 TCP 载荷,不发送探包,也不约束 UDP。
| 做法 | 谁在判断 | 失败时靠什么缩小 |
|---|---|---|
| 经典 PMTUD | 沿途路由器 | ICMP 包太大里的链路 MTU |
| 分组层探包 | 发送方这一层 | 探包得不到确认,或当前尺寸形成黑洞 |
| MSS 钳制 | 改写握手的设备 | 事先把 TCP 载荷上限写小 |
钳制只影响钳制之后新建的 TCP。已经握完手的连接、以及 UDP 和 QUIC,仍要回到路径 MTU。探包丢失若被当成普通丢包,还会牵动 拥塞控制。RFC 4821 允许实现把孤立的探包失败从拥塞反应里分开。某一系统有没有分开,本文没有测量。
QUIC 另有一条 1200 字节的规则。据 HTTP/3 与 QUIC 所引的 RFC 9000,承载 Initial 的 UDP 载荷要填充到至少 1200 字节,直接原因是限制放大。这和 RFC 8899 对 IPv4 基准包长的 1200 字节建议数字相同,含义不同:一个是握手数据报的填充下限,一个是探包搜索的起点。
入口不交回,内层就看不见
一个可独立引用的定义句:RFC 8899 第 1.1 节写明,路由器丢掉被封装的包时,产生的 ICMP 指向隧道入口。入口应处理差错里引用的报文、去掉封装的影响,再向原始发送方交回格式正确的 ICMP。这一步没有做,原始发送方就收不到包太大。
该节把入口的这份责任指向当时仍在起草的文档,不是另一份已经取代 RFC 1191 或 RFC 8201 的标准。本文只采用 RFC 8899 已经写明的结果:入口不转发,内层发送方看不到这条差错。
因此外层和内层是两次发现:
| 这一层 | 探的路径 | 包太大先到谁 |
|---|---|---|
| 本机到 VPN 服务器的外层 | 物理路径上的最小一跳 | 外层发送方,若差错没有被滤掉 |
| 隧道里的内层 | 封装之后的路径,头部已经占掉字节 | 先到隧道入口,再看入口是否交回 |
| 分割隧道下的直连 | 不进隧道的那一条 | 回到经典 ICMP 或本机自己的探包 |
出口之后的路由器若丢掉过大的内层包,差错的目的地址是隧道入口,不是用户机器上的原始应用。入口不翻译,应用仍按原来的尺寸发送。加密还会让入口或发送方看不清被引用的传输层头部,于是即使差错到了,也可能无法把它配到正确的流上。
一个可独立引用的结论句:隧道图标亮着,只说明内层包外面多了头部。它不表示探包已经量过整条到网站的路径,也不表示 ICMP 包太大已经交到了内层发送方。
本文不提供修改接口 MTU、钳制 MSS 或关闭探包的步骤。
现象对照
| 现象 | 更可能先看什么 |
|---|---|
| 很小的回显成功,大传输中途停住 | 经典黑洞:大包被丢,PTB 没有回到发送方 |
| TCP 大传输恢复,同样大小的 UDP 仍失败 | MSS 钳制只限制了新建的 TCP;UDP 仍在探或仍过大 |
| 偶尔一个大包失败,随后尺寸又升上去 | 孤立探包丢失是不确定的;连续失败才降低上限 |
| 只有进隧道的目的地出现大包失败 | ICMP 停在入口,或封装后的路径更短 |
| QUIC 握手失败,小 UDP 仍然通过 | 先分开看 Initial 的 1200 字节填充,再看探包 |
核对清单
- 先分清三条路:ICMP 包太大、分组层探包、TCP 的 MSS 钳制;
- IPv6 的经典文本用 RFC 8201:RFC 1981 已被它取代;
- TCP 与数据报各有一份探包规范:RFC 4821 仍在,RFC 8899 更新它、用于数据报;
- 一次探包丢失不算数:RFC 8899 的默认要连续失败到 3 次;
- 隧道里的差错先到入口:入口不交回,内层发送方看不到缩小提示。