武忠 于红增
(1 中国民用航空三亚空中交通管理站 海南 三亚 572000)
(2 中国电子科技集团公司第五十四研究所 河北 石家庄 050081)
随着计算机网络的发展,专用网络普遍采用IP技术来构建,语音、图像、视频和数据等各种IP分组业务逐渐成为网络业务的主流,基于UDP超大报文的软件系统由于通信的高效性和开发的便捷性在某专用网络中被广泛采用,由此带来的一系列QoS保障问题,这些问题多与IP报文分片有关。
在TCP/IP协议族中,链路层的报文叫做“帧”,每种链路层协议对数据帧的长度都有一个限制,这个特性称作最大传输单元 (Maxitum Transmission Unit,MTU)[1],单位为字节(Byte)。如常用的EthernetII网络MTU为1500,IEEE 802.3网络MTU为1492。如果IP层有一个数据报要传,而且数据的长度比链路层的MTU还大,那么IP层就需要分片,使每一片的长度都不大于MTU。
TCP/IP的设计原则是屏蔽低层物理网络技术细节,通过IP协议向上层提供统一的IP数据报。对于上层协议和应用而言,MTU作为低层物理细节己被IP层屏蔽,以太网物理帧格式和MTU的关系及IP报头结构如图1所示,报头长度为20~60 Bytes,其中有16 bit的总长度字段,用于指示整个IP数据报的长度(单位为字节),也就是说,IP数据报的长度最大可达65535 Bytes[2]。
图1 以太网MTU及IP报文格式
UDP报文大小由软件所决定,在不超过协议版本规定的数据报文大小的前提下,IP协议选择当前最合适的数据报文大小在物理网络上进行最大限度封装,链路层一般要限制每次发送数据帧的最大长度,该值即MTU。任何时候IP层接收到一份要发送的IP数据报时,要判断向本地哪个接口发送数据(选路),并查询该接口获得其MTU。把数据长度与MTU进行比较,前者大于后者则需要进行分片。分片可以发生在信源端上,也可以发生在网络中间节点上。把一份IP数据报分片以后,只有到达目的地才进行重新组装。重新组装由信宿端的IP层来完成,目的是使分片和重新组装过程对传输层(TCP和UDP)是透明的,除了某些可能的越层操作外,已经分片过的数据报在转发过程中有可能会再次进行分片(可能还不止一次)。
IP首部中包含的数据为分片和重新组装提供了足够的信息:标识字段、更多的片标志位和不分片标志位。查看图1中IP首部格式,下面这些字段用于分片过程。对于信源端发送的每份IP数据报来说,其标识字段都包含一个唯一值,该值在数据报分片时被复制到每个片中。标志字段用其中一个比特来表示“更多的片”。除了最后一片外,其他每个组成数据报的片都要把该比特置1。片偏移字段指的是该片偏移原始数据报开始处的位置。
另外,当数据报被分片后,每个片的总长度值要改为该片的长度值。最后,标志字段中有一个比特称作“不分片”位,如果将这一比特置1则IP不对数据报进行分片,如果需要进行分片但设置了不分片比特则把数据报丢弃,如果丢弃发生在中间节点上还会发送一个ICMP差错报文给信源端。IP报文分片的优点是为上层协议提供了一个透明的传输通道,使上层协议不必关心底层不同的硬件技术。
(1)TCP/UDP报文格式
一个UDP数据报由UDP首部和用户数据组成,一个TCP流报文由TCP首部和用户数据组成,如图2所示。UDP首部由8个字节组成,TCP首部由20个字节组成 (不含TCP选项字段时)。
图2 TCP/UDP报文格式
(2)分片协议
当传输层数据包在IP层进行分片后,每一片都具有自己的IP首部,因此可以看成一个完整独立的IP包,与其他分片的IP包是相互独立的。然而信宿端接收这些IP包时有可能不会按照原来的顺序接收,但是IP包的首部中有足够的信息,因此信宿端能正确还原出原来的传输层数据报。
UDP分片和TCP分片方式不同,从属于同一个TCP报文的每一个IP分片都包含有相同的TCP首部,而UDP报文分片后只在第一个分片有UDP首部,后续的UDP分片就没有UDP首部。信源端上发送2000 Bytes数据时UDP和TCP各自的分片结果,如图3所示。注意:用wireshark软件显示UDP分片结果时是最后一个分片的protocol为UDP,前面各个分片的protocol为IP,这是因为wireshark选择在重组完成后才在最后一个分片给出正确的protocol,查看各个分片,第一个分片的IP数据部分可以看到udp首部,后续分片则没有。
图3 TCP/UDP报文分片机理
在网络中路由器和交换机一般只有分片处理功能,而不执行分片重组功能。路由交换设备接收到一份要发送的IP数据报时,要判断向本地哪个接口发送数据(选路),并查询该接口获得其MTU。把数据长度与MTU进行比较,前者大于后者则进行分片,这往往发生在不同MTU网络交界处。如果出接口是隧道接口,IP数据报会被封装,参与比较的是隧道封装后的长度,而不是原始IP数据报长度。
这些设备出于自身功能需要(比如访问控制、防病毒和深度分析等等)都对分片报文进行重组[3],对于需要转发的报文则进行重新分片,分片的依据是下行链路的MTU,可能与信源端MTU不同。
终端设备总是要对超过MTU的上层报文打包成合适的IP报文进行传输(根据需要进行分片),对于收到的分片报文自动完成重组再上报给合适的应用程序。如果分片报文部分分片丢失,则该UDP报文因无法完成重组而丢弃。
由于输入输出端口链路层协议不同,输入接口和输出接口的帧格式和MTU往往不同,是否发生分片取决于所用的链路层协议和MTU。
UDP报文分片传输过程中,如果某个分片丢失会导致分片所属的那个UDP报文丢包,通常不会造成其他影响[4]。在实际的网络环境中,情况往往比较复杂,例如某安全设备外部链接了多条链路,都传输着UDP大包业务,其中一条链路有误码,导致部分UDP分片丢失,安全设备无法对其完成重组。由于安全设备不能及时丢弃这些分片,任其在缓冲区中等待重组完成,后续的类似分片积累起来将缓存占满,导致无法重组其他链路的UDP报文,这样一条链路上的UDP大包断续丢包之后,其他链路也出现UDP大包丢包。经过排查发现断开有损链路并重启安全设备后故障消失,接入有损链路后故障可以重现。确认该故障与UDP大包分片有关,该安全设备软件改为及时丢弃这些无法重组的分片后,故障消失。
终端在发送IP数据报时可以获知的只是第一跳MTU,针对超过MTU的IP数据报,依据该值进行第一次分片,在传输过程中如果遇到隧道协议导致链路出口MTU减小 (如GRE隧道协议有个8 Bytes的开销,PPPOE报文有8 Bytes的开销),则总尺寸超过链路MTU的那些分片会进行二次(甚至多次)分片[5],由此将产生新的IP短报文。
某业务软件发送7000 Bytes的UDP报文,加上UDP首部的8 Bytes,共7008 BytesIP数据需由网络层打包,第一跳MTU为1500 Bytes,UDP报文被分成了4个1500 Bytes的IP包(1480 BytesIP数据和20 BytesIP首部,8 BytesUDP首部包含在第一个分片IP数据中)和1个1108Bytes(剩余的1088BytesIP数据和20 BytesIP首部)的IP包,中间链路上存在GRE隧道,GRE封装占用8 Bytes,其MTU小于1500,于是4个1500Bytes的IP包被二次分片,产生4个1500Bytes的IP包和4个46 Bytes的短IP包,这个UDP报文将产生9个长短不一的IP分片,实际使用中受下游设备包转发能力的限制产生了丢包,在将信源网卡MTU手工改为较小的值1460之后,通信正常。
由于UDP分片报文只有第一片有UDP首部,后续的分片没有,因此在通过ACL匹配UDP报文的源端口、目的端口时只能匹配第一个分片,即基于五元组(源IP地址、目的IP地址、源端口、目的端口和协议)进行流分类并进行优先级标记时,同一个UDP报文的分片打不上相同优先级的情况。如果基于三元组(源IP地址、目的IP地址和协议),则会导致不同的应用打上相同的优先级标签,与需求不符。
现网中,各种VPN应用或接入技术其报文封装格式及大小因采用的技术不同会有比较大的差异。因此更要格外注意报文经过多次封装后MTU值的减小情况[6]。通常情况下,大部分应用程序都会允许报文分片的,但总有部分协议因为种种原因不允许报文分片,这就要求信源网卡MTU不能超过路径中MTU的最小值,否则可能会导致应用无法正常通信。
UDP报文分片在实际应用中的效果情况非常复杂,对QoS、业务连通性和设备性能等都有影响,与链路上设备特性有关,本文阐述了与UDP大包分片有关的一些故障案例及其故障机理,供大家在实际应用中参考。
[1]COMER D E.用TCP/IP进行网际互连[M].北京:电子工业出版社,1998.
[2]程 伟,全天彤.IP报文分片机制与路径MTU发现技术[J].计算机应用研究,2000(8):36-39.
[3]占幼平,刘 玉.一种基于业务流的IP分片实时识别方法[J].微计算机信息,2007(33):87-89.
[4]刘 阳.UDP数据报IP分片传输方式研究[J].今日中国论坛,2013(12):197.
[5]金旭燕.IP分片及其故障处理[J].科技信息,2013(24):264-265.
[6]秦昌潜.报文分片对网络的影响[J].中国集体经济,2012(9):176-177.