路径最大传输单元 (PMTU) 黑洞路由器
作者:Cable Guy
有关所有 Cable Guy 专栏文章的列表和其他信息,请单击此处
简介
Internet 协议 (IP) 是针对由以太网、帧中继等多种网络技术构成的网络的应用而设计的。每种网络技术都有不同的最大传输单元 (MTU),即其能发送的帧的最大大小。IP MTU 就是所能发送的 IP 包的最大大小。以以太网为例,以太网的 MTU 为 1526 字节。减去报头和报尾的大小(共 26 字节),以太网的 IP MTU 为 1500 字节。
为了适应各种网络技术不同的 IP MTU,IP 允许路由器将数据包进行分段。例如,如果数据包的大小超过了转发它的链路所允许的范围,则 IP 路由器会对数据包的有效负载进行分段,然后作为一个个的 IP 包(称为分段)进行发送。
虽然 IP 的这个特性考虑了网络层的独立性,但它也会长时间占用处理器并占用大量内存,进而对 IP 路由器的性能产生实质性的影响。因此,包括 Internet 在内的现代 IP 网络都通过以下方法避免由路由器对 IP 包进行分段:
• |
发送基于 UDP 的通信时,将 UDP 消息的最大大小设置为足够小,以防止 IP 路由器进行分段。 |
• |
发送基于 TCP 的通信时,将 IP 报头中的“不分段”(DF) 标记设置为 1,阻止 IP 路由器对 TCP 数据段进行分段。 |
当 TCP 对等方建立 TCP 连接时,它们会交换各自的 TCP 最大段大小 (MSS) 值。TCP 对等方会使用这两个 MSS 值中的较小值来建立 TCP 连接。以前,主机的 MSS 值是 MTU 减去用于 IP 和 TCP 报头的 40 字节。但是,为了支持额外的 TCP 选项(如时间戳和可选确认),典型的 TCP 和 IP 报头可增至 52 字节或更多字节。
当路由器必须将 IP 包分段但又因 DF 标记设置为 1 而不能分段时,路由器可采用以下任一种方式:
• |
发送符合 RFC 792 中最初定义的“ICMP Destination Unreachable-Fragmentation Needed and DF Set”消息,然后丢弃该包。 原始消息格式中不包含有关转发失败的链路的 IP MTU 的信息。 |
• |
发送符合 RFC 1191 中重新定义的“ICMP Destination Unreachable-Fragmentation Needed and DF Set”消息,然后丢弃该包。此新消息格式包含一个 MTU 字段,可指出转发失败的链路的 IP MTU。 RFC 1191 定义了路径 MTU (PMTU) 发现,它使得成对的 TCP 对等方能够动态地发现二者之间路径的 IP MTU,从而发现该路径的 TCP MSS。一旦收到符合 RFC 1191 定义的“Destination Unreachable-Fragmentation Needed and DF Set”消息,TCP 就会将该连接的 MSS 调整为指定 IP MTU 减去 TCP 和 IP 报头的大小。这样,在该 TCP 连接上发送的后续包就不会超过最大大小,无需分段即可在该路径上传输。 |
• |
直接丢弃包。 直接丢弃需分段但 DF 标记设置为 1 的包的路由器称为 PMTU 黑洞路由器。 |
检测 PMTU 黑洞路由器
PMTU 黑洞路由器会给 TCP 连接带来问题。例如,Microsoft® Windows® XP 和 Windows Server™2003 中的 TCP/IP 协议默认情况下会使用 PMTU 发现。TCP 会发送 DF 标记设置为 1 的数据段,并且在需要时,会根据符合 RFC 1191 定义的“ICMP Destination Unreachable-Fragmentation Needed and DF Set”消息的回执(其中包含 IP MTU),更改 TCP MSS 值。
在 TCP 三次握手期间交换的 TCP 数据段不会太大,因而不会被 PMTU 黑洞路由器丢弃。但是,一旦开始在连接上传输数据—假定基于协商的 MSS 确定的 PMTU 比实际 PMTU 大—TCP 数据段的大于实际 PMTU 的 IP 包就会被直接丢弃。
例如,您可以用 FTP 命令行工具成功地与 FTP 服务器建立连接并登录。但是,当您试图下载或者上载文件时,中间的 PMTU 黑洞路由器就会丢弃达到最大大小的 TCP 数据段,从而导致错误和文件传输失败。
您可以按照下面的语法使用 Ping 工具来检测 PMTU 黑洞路由器:
Pingdestination –f –lICMPEchoPayloadSize
• |
此处的 destination 可以是一个 IP 地址,也可以是一个可解析为 IP 地址的名称。 |
• |
-f 选项可将 DF 标记设置为 1。 |
• |
-l 选项指定 ICMP Echo 消息的有效负载的大小。 |
• |
ICMPEchoPayloadSize 是 ICMP Echo 消息的有效负载的字节数。 |
要计算 ICMPEchoPayloadSize,可用您想发送的 IP 包的大小减去 28。这是因为,IP 报头的大小为 20 字节,而 ICMP Echo 消息的 ICMP 报头的大小为 8 字节。下图显示了二者的关系。
例如,要发送长度为 1500 字节的 ICMP Echo 消息,您应使用以下命令:
ping destination –f –l 1472
如果有 IP MTU 更小的中间链路,且路由器发送了“ICMP Destination Unreachable-Fragmentation Needed and DF Set”消息,则 Ping 工具会显示“Packet needs to be fragmented but DF set”消息。如果有 IP MTU 更小的中间链路,且 PMTU 黑洞路由器直接丢弃了包,则 Ping 工具会显示“Request timed out”消息。
要找出包含
PMTU 黑洞路由器的
文章评论