在我的应用程序中,我使用以下命令打开一个原始套接字(LINUX内核3.8.5) 指令:
::socket( PF_PACKET, SOCK_RAW, htons((uint16_t)ETH_P_ALL));
一切正常,我能够接收它并将其发送到另一个界面。 不过有时候
::recvfrom()
该套接字上的返回1518(1504个有效负载字节+ 14个ETH_HLEN)。
当我尝试发送1518字节的缓冲区时,指令
::send(......)
返回EMSGSIZE(消息太长)。
请注意,在我的NIC接口上,MTU为1500,因此我预计会达到最大值 使用:: recvfrom
检索的1514(有效负载+ ETH_HLEN)字节数ethtype是0x0800所以它不是vlan标记帧,因此那4个字节“额外”不是由于vlan标记
你有解释吗?
答案 0 :(得分:0)
我的理解是MTU特定于连接,因为它取决于从源到目的地的整个路径 - 而不仅仅是本地接口。如果您发送的地址不同于您欺骗数据包的地址,那么MTU可能会有所不同。
启用PMTU发现后,内核会自动跟踪每个目标主机的路径MTU。当它通过connect(2)连接到特定对等体时,可以使用IP_MTU套接字选项方便地检索当前已知的路径MTU(例如,在发生EMSGSIZE错误之后)。它可能会随着时间而改变。对于具有许多目标的无连接套接字,也可以使用错误队列访问给定目标的新MTU(请参阅IP_RECVERR)。每个传入的MTU更新都会排队一个新错误。
答案 1 :(得分:0)
更多关于此事,我要调试问题我有这个配置:
的eth0(服务器1)--------------> eth0的(服务器2)----- ----- NAT> dummy0(服务器2)
Server1和Server2之间没有交换机,没有什么,只有一根电缆, 和dummy0是使用虚拟网络模块获得的NIC。嗅探eth0(Server1)" TX端"在eth0(Server2)" RX侧"这是什么 我得到了:
TX方面:
1514 bytes, sequence number 15476
1514 bytes, sequence number 15477
1514 bytes, sequence number 15478
1514 bytes, sequence number 15479
在RX方面,我期待相同但我得到:
1514 bytes, sequence number 15476
1518 bytes, sequence number 15477
1514 bytes, sequence number 15479
有趣的是,15478没有收到最后4个字节
在那些1518字节(序号15477)中是有效载荷中的前4个字节
丢失的eth包。
已解决:这是GRO选项,的确可以归功于:: rcv上的选项 一次获得2个或更多以太网帧,这就是为什么例如一个序列 号码"出现"失踪(实际上与前一个合并), 事实上,对于某些数据包我得到1518是由于缓冲区的大小已通过 在:: rcv,传递一个更大的缓冲区确实我没有丢失任何内容。