为什么UDP包分片过了路由器就收不到了?

转载一篇文章,解释了其中的原因:

http://blog.chinaunix.net/u/553/showart_179794.html

 

路径最大传输单元 (PMTU) 黑洞路由器 ZT

路径最大传输单元 (PMTU) 黑洞路由器 数据包在路由器上的分片

简介

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 黑洞路由器:

Ping destinationfl ICMPEchoPayloadSize

此处的 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 黑洞路由器的路径的有效 IP MTU,请使用 Ping 工具,同时不断增大 Echo 消息的有效负载的大小。因为典型子网的最小 IP MTU 是 576 字节,因此开始时可将 ICMP Echo 消息的有效负载设置为 548 字节,然后每次递增 100 字节,直到找到有效 PMTU。

例如,如果 ping 10.0.0.10 -f -l 972 命令显示“Reply from 10.0.0.10”,而命令 ping 10.0.0.10 -f -l 973 显示“Request timed out”,则 IP 地址为 10.0.0.10 的节点的有效 PMTU 为 1000 字节 (972+28)。

返回页首

PMTU 黑洞路由器的解决方案和工作方法

以下的 PMTU 黑洞路由器的解决方案和工作方法按照从最简单的解决方案到最困难的工作方法的顺序排列。

1. 配置中间路由器以支持路由器端 PMTU 发现

解决专用 Intranet 中的 PMTU 黑洞路由器问题的最简单的方法,是将您的所有路由器配置为支持路由器端 RFC 1191,并支持发送 ICMP Destination Unreachable-Fragmentation Needed and DF Set 消息(其中带有转发失败的链路的 IP MTU)。这与将路由器配置为支持主机端 RFC 1191 是有区别的,后者的路由器会对自己的 TCP 连接使用 PMTU 发现。

在 Internet 上进行通信时,通常不太可能将 Internet 路由器配置为支持路由器端 PMTU 发现。在这种情况下,您可以使用以下各节介绍的工作方法。

2. 启用 PMTU 黑洞路由器检测

基于性能方面的考虑,Windows 2000、Windows XP 和 Windows Server 2003 中默认关闭了 TCP/IP 的 PMTU 黑洞路由器检测。如无法将路由器配置为支持路由器端 RFC 1191,则可配置以下注册表设置:

Setting: EnablePMTUBHDetect
Key: HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters
Value Type: REG_DWORD
Value: 1

因为此注册表条目在默认情况下不存在,所以您必须使用注册表编辑器工具添加此条目,然后重启 Windows 使设置生效。

PMTU 黑洞路由器检测得到启用后,如果 TCP 数次重新传输某分段但仍未得到确认,则它会试图发送 DF 标记设置为 0 的分段。如果接收到对 DF 标记设置为 0 的分段的确认,则连接中后续分段的 MSS 将减小,且其 DF 标记会设置为 1。启用 PMTU 黑洞路由器检测会增加重新传输给定分段的最大次数,从而会影响整体性能。

3. 确定最佳 IP MTU 并通过 MTU 注册表设置来设置该值

启用 PMTU 黑洞路由器检测的替代方法,是根据本文前面部分的介绍使用 Ping 工具确定所有相关路径的 PMTU 值,然后使用注册表设置手动配置发送接口的 IP MTU。

该方法通过不停发送 DF 标记设置为 1,大小又不会导致 PMTU 黑洞路由器将其直接丢弃的 IP 包来避开 PMTU 黑洞路由器。手动指定 IP MTU 意味着所有通信量(包括本地子网通信量和不包含 PMTU 黑洞路由器的路径上的通信量)都将使用较小的 IP MTU。

确定有效的 PMTU 后,您可以通过以下步骤手动指定 TCP/IP 接口的 IP MTU:

1.

打开 Network Connections 文件夹,记下 LAN 连接的名称,如“Local Area Connection”。

2.

单击开始 ,单击“运行”,键入“regedit.exe”,然后单击“确定”。

3.

使用注册表编辑器工具的树图(左边窗格)打开如下键:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control /Network/{4D36E972-E325-11CE-BFC1-08002BE10318}

4.

此键下面是与已安装的 LAN 连接相关联的全局唯一标识符 (GUID) 的一个或多个键。这些 GUID 键中的每一个都有一个 Connection 子键。打开每个 GUID /Connection 键,寻找值与第一步中记下的 LAN 连接的名称匹配的 Name 设置。

5.

如果找到包含与 LAN 连接匹配的 Name 设置的 GUID /Connection 键,请写下或记下该 GUID 值。

6.

使用注册表编辑器的树视图打开如下键:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip /Parameters/Interfaces/GUID

7.

右键单击树视图中的“GUID”键,指向“新建”,然后单击“双字节值”。

8.

在注册表编辑器工具的内容窗格(右窗格)中,为新注册表设置的值键入 MTU ,然后按 ENTER

9.

在内容窗格中,双击新的 MTU 设置,并在“编辑双字节值”对话框中选择“十进制”,然后在“数值数据”中键入有效 MTU 值。

10.

单击“确定”。关闭注册表编辑器工具。

11.

重新启动计算机使 MTU 设置生效。

4. 禁用 PMTU 发现

如果确定网络上基于 Windows 计算机的所有 LAN 接口的合适的 PMTU 值并进行配置不太可行,则可以使用最后一招:禁用 PMTU 发现。我们不推荐使用此方法,因为如果禁用 PMTU 发现,所有远程目的地的 IP MTU 都将设置为 576 字节,而这会影响性能。

要关闭 PMTU 发现,请配置如下注册表设置:

Setting: EnablePMTUDiscovery
Key: HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters
Value Type: REG_DWORD
Value: 0

因为此注册表条目在默认情况下不存在,所以您必须使用注册表编辑器工具添加此条目,然后重启 Windows 使设置生效。

你可能感兴趣的:(windows,网络,tcp,工具,internet,路由器)