执行路径 MTU 发现,而不依赖于通常不会传递的 ICMP 错误。
该程序执行 RFC 4821 中所述的分组层路径 MTU 发现,这是在存在 ICMP 黑洞的情况下检测 MTU 大小的更可靠方法。
虽然 TCP 连接会根据各种指标(网络性能、数据包丢失、ICMP 错误消息等)自动调整 MTU 大小,但无连接协议的情况并非如此。
当性能至关重要时,吞吐量、数据包分段和路由可靠性是需要分析的三个关键指标,以优化流性能。由于路由可靠性并不总是取决于我们,因此我们应该努力最大化吞吐量,同时不执行数据包分段,这会严重降低性能[1] 。
路径 MTU 发现的最初提议依赖于当设置了“不分段”字段的 IPv4 数据包太大而无法传播时, ICMP Fragmentation Needed
数据包。不幸的是,一些路由器不会生成此类错误,而是选择默默地忽略大数据包。客户端无法确定丢包的原因。
由于所有主机都必须支持 ICMP_ECHO 查询,因此我们可以利用 ICMP 消息接受任意数量的数据并将不同大小的数据包发送到我们的服务器的事实。如果我们打开 IPv4 数据包中的“不分段”字段并侦听响应,我们实际上是在等待 ACK(以 ICMP_ECHOREPLY 数据包的形式)确认此 MTU 大小有效。
现在我们只需对数据包的大小执行二分查找即可找到该路由支持的最大 MTU 大小。
当处于ICMP模式时,会产生一些不同大小的ICMP_ECHO请求。
ICMP Fragmentation Needed
),则该 MTU 大小将被声明为无效并降低阈值。ICMP 模式的唯一要求是主机必须能够回复 ping 消息。
相同的算法适用于 UDP 数据包,但您需要在接收主机上运行服务器 ( udp_server.py ) 才能发回确认消息。
该程序应该可以在大多数 Linux 发行版和 OSX 上正常运行。
gcc -Wall -Wextra mtu_discovery.c mtu.c -o plpmtu
它不应报告警告/错误。如果是这样,请打开一个问题。
如果您想在ICMP 模式下运行,请键入:
sudo ./plpmtu -p icmp -s <server-ipaddr>
如果您想运行UDP 模式:
sudo ./plpmtu -p udp -s <server-ipaddr:port>
需要管理员权限才能使用原始套接字。
说明符 | 描述 |
---|---|
-p {icmp/udp} | 选择要运行的模式。 |
-s <地址[:端口]> | 指定服务器地址。如果在 UDP 模式下运行,还必须通过附加 ':port' 来指定目标端口(例如-s 8.8.8.8:12345 ) |
-l <地址:端口> | 选修的。选择要绑定的地址();用于UDP模式;可能会被删除。 |
-t <超时> | 选修的。选择等待服务器响应的最长时间,默认为1秒;时间以毫秒表示。 |
-r <最大要求> | 选修的。选择声明 MTU 大小无效所需的最大失败尝试次数,默认为 3 次尝试。 |
sudo ./plpmtu -p icmp -s 184.12.26.131
使用 184.12.26.131 执行 MTU 发现(ICMP 模式)。
sudo ./plpmtu -p udp -s 184.12.26.131:24000 -t 1500 -r 5
使用184.12.26.131在24000端口进行MTU发现(UDP模式)。如果连续5次1.5秒内没有收到响应,请降低MTU阈值。