【发布时间】:2013-10-14 09:25:27
【问题描述】:
非常奇怪的行为...
我有 3 台机器:
------------ ------------ ------------ | A (x86) |-----| B (x86) |-----| C(手臂)| |发件人 | |接收器 | |发件人 | ------------ ------------ ------------- A 和 B 是 Linux (Ubuntu 12.04) 机器,内核 3.2;
- C 是 android (ICS) 机器,内核 3.0.8;
- 全部通过 RJ45 电缆连接;
- 连接正常,网络设置正确;
问题是:当机器 C (ARM-android) 发送一个有效负载大小超过 1472 字节的 UDP 数据包(数据包被分片之前的最大有效负载)时,机器 B 上的服务器应用程序永远无法收到它,...关于那个:
- 源/目标 IP 地址正确:如果我将有效负载大小设置为小于或等于 1472,我可以接收我发送的所有数据报;
- 在机器 B(接收方)上,如果我用 Wireshark 转储网络流量,我可以看到每个片段,然后重新组装消息 => 从 Wireshark 的角度来看,一切都很好!
- 比较每个片段标头以及重新组装的消息与从机器 A 发送相同消息时我可以转储的消息(始终接收正常),一切似乎都很完美(唯一的区别是 IP 地址和校验和,因为UDP 标头校验和考虑 IP 地址字段)。
- 没有 MTU 问题,数据包按预期分段。
- 机器之间没有路由器/交换机
- ifconfig 未显示数据包丢失、溢出或任何其他经典错误!
- ...这太奇怪了!!
我在互联网上花了一些时间,但从未找到过类似的话题。每当人们遇到 UDP 问题时,要么他们的 MTU 发现不正确,要么他们在测试过程中做了一些错误处理,或者他们无法将消息转储到接收主机上,......这里不是这种情况!!
当然,我知道问题出在发送端(机器 C),但也许更容易在接收端启用一些日志(在内核级别?)以了解为什么 UDP 数据报消失!?有什么建议吗?是否有我可以在 /proc/sys/net 中签入的特定文件,或者我应该启用的内核选项?
非常感谢。
【问题讨论】:
-
尽管您可以确定请发布所有地址:端口子网值
-
我终于找到了问题。
-
我终于找到了问题所在。在机器 B 的 Linux 内核中添加跟踪,我已经能够理解数据报由于错误的有效负载校验和(重新组装后)而被丢弃。一段时间后,我发现机器 C 的 NIC 计算了所有数据包的 UDP 校验和,无论它们是否是片段。这导致所有片段有效负载的字节 7 和 8 被此校验和覆盖。我现在已经解决了 NIC 卡设置中的问题,一切都很好。还是非常感谢!
-
你是如何阻止 NIC 在片段中计算 UDP 校验和的?
标签: android linux debugging udp kernel