丢弃大于 1500 字节的 UDP 数据包

Posted

技术标签:

【中文标题】丢弃大于 1500 字节的 UDP 数据包【英文标题】:UDP packet greater than 1500 bytes dropped 【发布时间】:2011-06-02 13:42:12 【问题描述】:

我正在开发一个 tftp 客户端和服务器,我想动态选择 udp 负载大小以提高传输性能。

我已经用两台 linux 机器测试了它(一台有千兆以太网卡,另一台有快速以太网卡)。我把千兆网卡的MTU改成2048字节,另一个留1500。

我使用setsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &optval, sizeof(optval))MTU_DISCOVER 标志设置为IP_PMTUDISC_DO

根据我的阅读,此选项应将 DF 位设置为 1,因此应该可以找到网络的最小 MTU(具有最低 MTU 的主机的 MTU)。然而,当我发送一个大小大于我发送数据包的机器的 MTU 的数据包时,这件事只会给我一个错误。

另外另一台机器(在这种情况下是服务器)没有接收到超大数据包(服务器的 MTU 为 1500)。所有的UDP包都被丢弃,唯一的办法是发送1472字节的包。

为什么主机要这样做?根据我的阅读,如果我发送的数据包大于 MTU,ip 层应该对其进行分段。

【问题讨论】:

如果 MTU 发现开启,IP 层还会对数据包进行分段吗? DF 位不能防止碎片吗? 离场。那么发送主机应该自己发现MTU吗?还是底层图书馆为他做的? 感谢大家的回复。我应该添加一些关于我的实验的内容。我尝试过使用 tracepath (此实用程序执行路径 MTU 发现)。我已将 MTU 设置为 4096,当我启动 tracepath 时,我自己的主机说消息太长,因此 tracepath 减小了消息大小。然而,就消息通过本地主机而言,没有其他主机会发出错误信号。 Tracepath 将继续发送 4096 字节长的消息,远程主机将愉快地丢弃它们,而不发送 ICMP 回复。 您需要记住,ICMP 交付是尽力而为,不可靠,而且许多防火墙都配置为只允许 ICMP 回显数据包,而不允许其他类型。 【参考方案1】:

我看不到问题所在。您正在设置“不分段”位,并且您发送的包小于发送主机的 MTU,但大于接收主机的 MTU。当然没有人会在这里分片(这样做会违反 DF 位)。相反,发送主机应该收到一条 ICMP 消息。

编辑:IP 指定将 ICMP 错误消息类型 3(目标不可达)代码 4(需要分片,但设置了 DF 位)发送到分片将具有的源主机发生了。 TCP 层自行处理此问题以进行 PMTU 发现。在无连接套接字上,如果激活了 IP_RECVERR 选项,Linux 会在套接字的错误队列中报告错误;见ip(7)。

【讨论】:

ICMP 类型 3 代码 4 表示“需要分段,并设置 DF 标志”。我不确定您如何在 linux 上收听该消息。我相信 ICMP 有效负载包含足够的信息以将其与特定的套接字相匹配,在这种情况下,如果您启用了它,您可能会将其作为 OOB 数据获取。或者未来的sendto() 调用可能会因ECONNRESET 而失败。 感谢您的回复。所以我应该设置 IP_RECVERR 标志然后搜索错误队列,对吗?我只是尝试验证 sendto 是否给了我一个错误,在这种情况下,我控制错误是否为“消息太长”,从而减少数据报的大小。按照你的说法,事情不是这样工作的,对吧? @Alex:不,这行不通。当发送UDP包时,内核不知道接收者将无法接收它。由于在成功传输的情况下通常不会在 UDP 中得到响应,因此 send 调用会立即返回(或仅在本地错误检查之后,例如缺少网络连接)。我没有尝试过 IP_RECVERR,但是是的,我认为它应该是这样工作的。 谢谢。我会尝试使用 IP_RECVERR。 如果这两个主机在同一个子网上,则不会收到 ICMP 错误消息,因为具有较小 MTU 的接收主机上的 IP 层甚至从未看到数据包 - 它在较低层被丢弃因为太大了。在同一子网中配置具有不同 MTU 的两台主机是完全不正确的。【参考方案2】:

您设置的“DF 位”代表“不要分段”。当您告诉 IP 层不要分段数据包时,不应期望它分段。

【讨论】:

【参考方案3】:

在同一子网1运行具有不同接口 MTU 的主机是正确的。

这是主机/网络配置错误,在这种情况下,IP 路径 MTU 发现预计无法正常工作。

如果您希望测试应用程序的路径 MTU 发现,您需要设置由路由器连接的多个子网2,具有不同的 MTU。在这种情况下,路由器是接收 MTU 不匹配的设备,并发送回 ICMP“需要分段”错误。


1.嗯,从技术上讲,相同的广播域2。作为“家庭路由器”出售的设备实际上是路由器/交换机——它们在 WAN 和 LAN 之间路由,但在 LAN 上的以太网端口之间切换。这不足以分隔具有不同 MTU 的网络。

【讨论】:

感谢您的回复。所以“需要分段”的东西是相对于 IP 层的。我应该使用路由器或第 3 层交换机才能使事情正常工作。我不知道家用路由器是dsl路由器+二层交换机,我以为它们可以作为局域网的三层交换机工作。 @Alex Vitale:是的,没错。您可以将具有两个 NIC 的机器配置为路由器以进行测试。

以上是关于丢弃大于 1500 字节的 UDP 数据包的主要内容,如果未能解决你的问题,请参考以下文章

C#多播UDP数据包丢弃,同时存储对象

为啥数据报很少超过1500字节

wireshark抓包大于1500字节和提示checksum offload的原因

c#,socket无法接收分片的UDP数据包

局域网中一个 UDP 包可以装多少数据?

udp 隧道中的数据包丢弃和拆分