某些数据包没有到达目标主机,我有一个很奇怪的问题。 当我们传送比MTU稍大的POST时,就会发生这种情况。 我们可以用这个脚本重现它:
#!/usr/bin/python import urllib2 magic_length = 2297 logurl = 'http://www.example.nl/' data = (magic_length - len(logurl)) * 'X' headers = {'content-type': 'application/x-www-form-urlencoded', 'User-Agent': 'Fake'} request = urllib2.Request(logurl, data, headers) handler = urllib2.build_opener(urllib2.HTTPHandler()) answer = handler.open(request, timeout=5)
发送方没有收到ACK并重传。 接收方从来没有看到它。
这取决于你在哪里运行脚本,以及你在哪里发布。 我的家庭连接是失败的(顺便说一下,自从几个月以来,我一直有AJAX POST的问题,因为我有一个新的调制解调器)。
如果我将发送机器的MTU减less100,那么它再次工作。 但是,如果我把magic_length减less100,它magic_length失败。 第一个理论是,我的一层ADSL(如PPPoA)添加了报头,导致数据包被错误地分割,但似乎并不是这样。
也许MTU发现出了问题。 有些跳线阻止所有的ICMP也许? 这是从我家到谷歌的traceroute的第一部分:
traceroute to google.com (74.125.133.102), 30 hops max, 60 byte packets 1 dsldevice.lan (192.168.2.254) 0.453 ms 0.547 ms 0.636 ms 2 195.190.243.7 (195.190.243.7) 29.836 ms 29.947 ms 29.986 ms 3 nl-zl-dc2-git-cr02.kpn.net (213.75.64.237) 37.004 ms 37.153 ms 37.204 ms 4 nl-rt-dc2-ice-ir02.kpn.net (213.75.64.236) 37.261 ms 37.300 ms 37.339 ms 5 72.14.198.161 (72.14.198.161) 38.351 ms 38.395 ms 38.405 ms 6 209.85.254.92 (209.85.254.92) 37.976 ms 38.103 ms 37.972 ms 7 209.85.253.247 (209.85.253.247) 38.612 ms 72.14.238.153 (72.14.238.153) 33.709 ms 209.85.253.249 (209.85.253.249) 36.890 ms 8 209.85.240.158 (209.85.240.158) 41.052 ms 41.104 ms 209.85.244.102 (209.85.244.102) 41.164 ms 9 209.85.249.12 (209.85.249.12) 38.392 ms 209.85.249.14 (209.85.249.14) 38.247 ms 38.851 ms^C
如果我ping 213.75.64.237,我得到(我从来没有实际上看过“数据包过滤”作为对STDOUT响应…):
PING 213.75.64.237 (213.75.64.237) 56(84) bytes of data. From 213.75.64.237 icmp_seq=1 Packet filtered
其余的我可以平。
这个答案似乎相似。 但是,我的脚本没有设置DF(不分片)标志(编辑:更正,tcpdmp确实显示在POST请求上设置了该标志),当我运行时,也不能看到ICMP请求返回给我在工作的主机上的脚本。 另外,数据包已经被发送方分割,发送第二个数据包失败。
我如何继续? 互联网服务供应商的国家石油公司很难达到目标,所以我需要certificate发生了什么事情。 他们不会帮我弄明白的
编辑:确认或否认ICMPtypes4(需要分片)的假设,我这样做:
$ ping -c 1 -M do -s 1472 host PING host (1.2.3.4) 1472(1500) bytes of data. 1480 bytes from host (1.2.3.4): icmp_req=1 ttl=50 time=33.8 ms
这工作,但我有点困惑。 “(1500)”是指总的碎片大小吗? 我假设是这样,因为1480字节+ 20字节的IP头是1500字节。
如果我增加一个ping的大小:
$ ping -c 1 -M do -s 1473 host PING host (1.2.3.4) 1473(1501) bytes of data. From pannekoek.lan (192.168.2.5) icmp_seq=1 Frag needed and DF set (mtu = 1500)
所以,这意味着两台主机之间的path确实允许1500字节的数据包,并且不会发生碎片问题。 看来我已经回到原点了。
再次编辑:我发现了一些重要的东西。 问题在于某些尺寸的数据包没有到达。 它发生在我的调制解调器和ISP的第一个网关之间:
$ for i in `seq 1025 1030`; do ping -c 1 -M do -s $i 195.190.243.7; done PING 195.190.243.7 (195.190.243.7) 1025(1053) bytes of data. 1033 bytes from 195.190.243.7: icmp_req=1 ttl=254 time=31.2 ms <- works --- 195.190.243.7 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 31.273/31.273/31.273/0.000 ms ========================== PING 195.190.243.7 (195.190.243.7) 1026(1054) bytes of data. --- 195.190.243.7 ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms <- packet loss ========================== PING 195.190.243.7 (195.190.243.7) 1027(1055) bytes of data. --- 195.190.243.7 ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms <- packet loss ========================== PING 195.190.243.7 (195.190.243.7) 1028(1056) bytes of data. --- 195.190.243.7 ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms <- packet loss ========================== PING 195.190.243.7 (195.190.243.7) 1029(1057) bytes of data. --- 195.190.243.7 ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms <- packet loss ========================== PING 195.190.243.7 (195.190.243.7) 1030(1058) bytes of data. 1038 bytes from 195.190.243.7: icmp_req=1 ttl=254 time=31.1 ms <- works --- 195.190.243.7 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 31.177/31.177/31.177/0.000 ms
我想我必须说服他们这是他们的问题。
从A点到B点的某个地方,路由器configuration了一个较低的MTU,这就是破坏事情的原因。 你有没有尝试做一个跟踪,看看到底ICMP数据包正在丢失?