MTU & MSS 详解

需要注意的是,区别两种帧封装格式:802标准帧和以太网帧

1,在802标准定义的帧格式中,长度字段是指它后续数据的字节长度,但不包括C R C检验码。RFC 1042(IEEE 802)

2,RFC 894(以太网)

所以,以太网帧报头为目的地址6+源地址6+类型2+CRC 4=18bytes

而802帧没有CRC,所以为14bytes。Sniffer采用的是802帧为14bytes

 

MTU: Maxitum Transmission Unit 最大传输单元
MSS: Maxitum Segment Size 最大分段大小

由于以太网EthernetII最大的数据帧是1518Bytes,这样,刨去以太网帧的帧头(DMAC目的地址MAC48bit=6Bytes+SMAC源MAC地址48bit=6Bytes+Type域2bytes)14Bytes和帧尾CRC校验部分4Bytes(这个部分有时候大家也把它叫做FCS),那么剩下承载上层协议的地方也就是Data域最大就只能有1500Bytes. 这个值我们就把它称之为MTU。

以太网的MTU是1500,再减去PPP的包头包尾的开销(8Bytes),就变成1492。

MSS就是TCP数据包每次能够传输的最大数据分段。为了达到最佳的传输效能TCP协议在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的时候往往用MTU值代替(需要减去IP数据包包头的大小20BytesTCP数据段的包头20Bytes)所以往往MSS为1460。通讯双方会根据双方提供的MSS值得最小值确定为这次连接的最大MSS值。

 

MTU

先说说这MTU最大传输单元,这个最大传输单元实际上和链路层协议有着密切的关系,让我们先仔细回忆一下EthernetII帧的结构DMAC+SMAC+Type+Data+CRC。由于以太网传输电气方面的限制,每个以太网帧都有最小的大小64bytes最大不能超过1518bytes,对于小于或者大于这个限制的以太网帧我们都可以视之为错误的数据帧,一般的以太网转发设备会丢弃这些数据帧。(注:小于64Bytes的数据帧一般是由于以太网冲突产生的“碎片”或者线路干扰或者坏的以太网接口产生的,对于大于1518Bytes的数据帧我们一般把它叫做Giant帧,这种一般是由于线路干扰或者坏的以太网口产生)

由于以太网EthernetII最大的数据帧是1518Bytes这样,刨去以太网帧的帧头(DMAC目的MAC地址48bit=6Bytes+SMAC源MAC地址48bit=6Bytes+Type域2bytes)14Bytes和帧尾CRC校验部分4Bytes(这个部门有时候大家也把它叫做FCS),那么剩下承载上层协议的地方也就是Data域最大就只能有1500Bytes这个值我们就把它称之为MTU。这个就是网络层协议非常关心的地方,因为网络层协议比如IP协议会根据这个值来决定是否把上层传下来的数据进行分片。就好比一个盒子没法装下一大块面包,我们需要把面包切成片,装在多个盒子里面一样的道理。

当两台远程PC互联的时候,它们的数据需要穿过很多的路由器和各种各样的网络媒介才能到达对端,网络中不同媒介的MTU各不相同,就好比一长段的水管,由不同粗细的水管组成(MTU不同 :))通过这段水管最大水量就要由中间最细的水管决定。

对于网络层的上层协议而言(我们以TCP/IP协议族为例)它们对水管粗细不在意它们认为这个是网络层的事情。网络层IP协议会检查每个从上层协议下来的数据包的大小,并根据本机MTU的大小决定是否作“分片”处理。分片最大的坏处就是降低了传输性能,本来一次可以搞定的事情,分成多次搞定,所以在网络层更高一层(就是传输层)的实现中往往会对此加以注意!有些高层因为某些原因就会要求我这个面包不能切片,我要完整地面包,所以会在IP数据包包头里面加上一个标签:DF(Donot Fragment)。这样当这个IP数据包在一大段网络(水管里面)传输的时候,如果遇到MTU小于IP数据包的情况,转发设备就会根据要求丢弃这个数据包。然后返回一个错误信息给发送者。这样往往会造成某些通讯上的问题,不过幸运的是大部分网络链路都是MTU1500或者大于1500。

对于UDP协议而言,这个协议本身是无连接的协议,对数据包的到达顺序以及是否正确到达不甚关心,所以一般UDP应用对分片没有特殊要求。

对于TCP协议而言就不一样了,这个协议是面向连接的协议,对于TCP协议而言它非常在意数据包的到达顺序以及是否传输中有错误发生。所以有些TCP应用对分片有要求---不能分片(DF)。

PPPoE

花开两朵,各表一枝,说完MTU的故事我们该讲讲今天的第二个猪脚---PPPoE

所谓PPPoE就是在以太网上面跑PPP协议,有人奇怪了,PPP协议和Ethernet不都是链路层协议吗?怎么一个链路层跑到另外一个链路层上面去了,难道升级成网络层协议了不成。其实这是个误区:就是某层协议只能承载更上一层协议。

为什么会产生这种奇怪的需求呢?这是因为随着宽带接入(这种宽带接入一般为Cable Modem或者xDSL或者以太网的接入)由于以太网缺乏认证计费机制而传统运营商是通过PPP协议来对拨号等接入服务进行认证计费的,所以就出了这么一个怪胎:PPPoE。(有关PPPoE的详细介绍参见V大以及本站其他成员的一些介绍文章,我就不啰里啰唆的了)

PPPoE带来了好处,也带来了一些坏处,比如:二次封装耗费资源,降低了传输效能等等,这些坏处俺也不多说了,最大的坏处就是PPPoE导致MTU变小了以太网的MTU是1500,再减去PPP的包头包尾的开销(8Bytes),就变成1492。

如果两台主机之间的某段网络使用了PPPoE那么就会导致某些不能分片的应用无法通讯。

这个时候就需要我们调整一下主机的MTU,通过降低主机的MTU,这样我们就能够顺利地进行通讯了。

MSS

当然对于TCP应用而言还有另外的解决方案。马上请出今天第三位猪脚:MSS。

MSS最大传输大小的缩写,是TCP协议里面的一个概念。MSS就是TCP数据包每次能够传输的最大数据分段。为了达到最佳的传输效能TCP协议在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的时候往往用MTU值代替(需要减去IP数据包包头的大小20BytesTCP数据段的包头20Bytes)所以往往MSS为1460。通讯双方会根据双方提供的MSS值得最小值确定为这次连接的最大MSS值。

我们回过头来看前言里面的那个问题,我们试想一下,如果我们在中间路由器上把每次TCP连接的最大MSS进行调整这样使得通过PPPoE链路的最大MSS值加上数据包头包尾不会超过PPPoE的MTU大小1492这样就不会造成无法通讯的问题。

所以上面的问题可以通过ip tcp adjust-mss 1452来解决。

当然问题也可以通过修改PC机的MTU来解决。

 

个人总结:

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(不能分段)

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值