问题更新:除了下面的问题,似乎我们使用Linux PLPMTUD机制的客户端/服务器应用程序变得太大路径MTU。有没有人看到这个,即实际路径MTU是1500,但getsockopt w TCP_MAXSEG返回端点的MTU:s,在我们的例子中是3000?我尝试用ethtool转换GRO,GSO和TSO,但错误仍然存在。普通ping只能管理1472个字节或更小的数据包。另外值得一提的是,PLPMTUD完美适用于较小的MTU:s。例如,w个端点在1500MTU和中间路由器的一个接口设置为例如1200MTU,则内核TCP探测并报告正确的TCP_MAXSEG(1200-报头)。TCP_MAXSEG不准确? (问题:Linux路径MTU探测无法使用accept():ed socket(如果使用setsockopt()请求)
我在应用程序中使用符合Linux RFC4821的打包层路径MTU发现。基本上,客户端不上的TCP套接字一个setsockopt的:
setsockopt的(FD,SOL_IP,IP_MTU_DISCOVER,& SOPT,的sizeof(SOPT)) 与选项值设置为IP_PMTUDISC_PROBE。 setsockopt不会返回错误。
客户端向丢弃服务器发送大型tcp数据包,并且通过Linux内核校准路径MTU - tcpdump显示DF位集被发送的tcp数据包,数据包大小变化直到内核知道路径MTU。但是,为了让它在另一个方向上工作(侦听服务器接受:从客户端连接,发送数据并在从服务器到客户端的方向上校准PMTU),我必须设置tcp path mtu discovery的全局选项/ proc/sys/NET /支持IPv4/tcp_mtu_probing。如果我不这样做,服务器将愚蠢地继续发送过大的数据包,这些数据包会被没有发回ICMP的中间路由器丢弃。两个端点的MTU均设置为3000,而中间跳数为MTU 1500.
我希望有人对错误发生了解。如果需要更多信息,请告诉我,并编辑问题。 Linux内核4.2.0和3.19.0都存在问题,都是库存Kubuntu LTS内核。 (x86/x86-64)
我在所有accept:ed套接字上设置了相同的套接字选项服务器端,然后再反向发送数据。
尝试在监听套接字而不是接受的套接字上设置套接字选项。它会被它们继承。在接受的套接字上设置它可能为时已晚,因为连接握手已经发生,窗口缩放协商等。 – EJP
@EJP:好主意,但我早些时候尝试过没有成功。 –
听起来好像您有一个中间路由器会中断正确的路径MTU发现,因此,毫不奇怪,路径MTU发现不起作用,除非您启用解决方法。究竟是什么神秘?通过向管理它的人抱怨来修复中间路由器。 –