From: http://infotech.blog.51cto.com/391844/123859
MTU=MSS+IP header+TCP header+ 链路层开销 + 加密报文头(某些程序加密强度不一样)
MTU ,对 UDP 和 TCP 报文都检测,当超过时,如果报文 DF=0 ,就进行分段,如果 DF=1 ,就丢弃,同时返回 RFC 792 定义的 ICMP Type3 Code 4 ( ICMP Destination Unreachable-Fragmentation Needed and DF Set )或 RFC 1191 定义的 ICMP 包(包含转发失败链路的 MTU ),主机收到后会调节 MSS 以适应,后续包不会分片就可进行传输。如果两端之间某 Router 配置了 ACL , deny 掉所有的 ICMP ,那就无法收到咯。
MSS 其实就是 TCP 报文 payload 大小。一般的应用软件,当客户端和服务器端在建立 TCP 连接的时候需要根据实际传输的报文大小来协商 TCP 的窗口大小 MSS 。 Tcp 连接成功后会进行两次滑动窗口的协商 , 一次是 pc 与 server ,一次是与网关,然后在两次协商里选择一个较小的值作为窗口来发送报文。
当协商出来的 MSS 比较大时,加上 IP header+TCP header+ 链路层开销 + 加密报文头后,就有可能大于 MTU ,当 DF=1 时,就会丢弃掉。
正如 所说:“对于 UDP 协议而言,这个协议本身是无连接的协 议,对数据包的到达顺序以及是否正确到达不甚关心,所以一般 UDP 应用对分片没有特殊要求。”所以在路由 器上进行 ip tcp mss 命令只对 tcp packet 检测就够了。
再提供一个案例: MSN 是使用 https 方式登陆的,有时会有突发大报文,而且 DF 位是设置为 1 的。虽然目前大部分出现的故障现象都是:不能发送附件;不能打开网页等。都是在 PPPoE 中发生的。但就算源和目的网络的 MTU 都是 1500 ,但是由于中间经过的节点链路可能存在不同,可能少于 1500 。或者在传输过程中的某个路由器设置了较小的 MTU 。而往往配置路由器或交换机时, 习惯禁止了所有的 ICMP 信息,这样的话那路由器就无法返回 ICMP 3/4 的包给源主机了。 RFC 2923 ( TCP Problems with Path MTU Discovery )。
所以,有时候出现的故障,不止要调试 MTU 值,还要调试 MSS 值,才能使所有应用正常
其实碰到此问题时,最好是借助 Sniffer 抓包分析(不过奇怪,锐捷 NBR1000 无法抓到 ICMP Type 3 Code 4 的包,所以无法抓包提供分析图,好可惜!是路由器不支持还是其他原因,以后有机会考证)
附: Sniffer 抓包协助理解分片过程以及 DF
上图是: Ping –l 2000 [url]www.163.com[/url]
首先看 IP header , More fragments 位为 1 ,向对方通告此数据包为多帧发送(分段), total lengt=1300bytes ( 1280bytes+IP 报头 20bytes )。再看 ICMP 处,可以看到分了两个包,大小分 别为 1280bytes 和 728bytes , 2008 bytes of reassembled data 指明重组后的数据为 2008bytes ( icmp 包头 8bytes ,数据 2000bytes )。然后看 DLC 部分,指明了以太类型 0800 ( IP ),帧大小为 1314bytes ( ICMP 的 1280bytes+IP 报头 20bytes+ 帧 14bytes )
再接着看下一个帧。首先看到 DLC 部分写着了帧大小为 762bytes , IP 部分, continuation of frame 17 ,第 17 个帧的后续。 Fragment offset 分段偏移量为 1280bytes (第一个包的大 小)。至此,第一个 icmp echo 包全部发送完毕。
ping –f –l 1200 [url]www.163.com[/url]
-f 命令:将数据报 DF ( don’t fragment )位设置为 1 (不能分段)
本文出自 “我是木头 ” 博客,请务必保留此出处http://infotech.blog.51cto.com/391844/123859