浅析TCP/IP协议,分片

1. TCP socket的buffer

每个TCP socket在内核中都有一个发送缓冲区和一个接收缓冲区,TCP的全双工的工作模式以及TCP的流量(拥塞)控制便是依赖于这两个独立的buffer以及buffer的填充状态。接收缓冲区把数据缓存入内核,应用进程一直没有调用recv()进行读取的话,此数据会一直缓存在相应socket的接收缓冲区内。再啰嗦一点,不管进程是否调用recv()读取socket,对端发来的数据都会经由内核接收并且缓存到socket的内核接收缓冲区之中。recv()所做的工作,就是把内核缓冲区中的数据拷贝到应用层用户的buffer里面,并返回,仅此而已。进程调用send()发送的数据的时候,最简单情况(也是一般情况),将数据拷贝进入socket的内核发送缓冲区之中,然后send便会在上层返回。换句话说,send()返回之时,数据不一定会发送到对端去(和write写文件有点类似),send()仅仅是把应用层buffer的数据拷贝进socket的内核发送buffer中,发送是TCP的事情,和send其实没有太大关系。接收缓冲区被TCP用来缓存网络上来的数据,一直保存到应用进程读走为止。对于TCP,如果应用进程一直没有读取,接收缓冲区满了之后,发生的动作是:收端通知发端,接收窗口关闭(win=0)。这个便是滑动窗口的实现。保证TCP套接口接收缓冲区不会溢出,从而保证了TCP是可靠传输。因为对方不允许发出超过所通告窗口大小的数据。 这就是TCP的流量控制,如果对方无视窗口大小而发出了超过窗口大小的数据,则接收方TCP将丢弃它。
查看测试机的socket发送缓冲区大小,cat /proc/sys/net/ipv4/tcp_wmem

第一个值是一个限制值,socket发送缓存区的最少字节数;
第二个值是默认值;
第三个值是一个限制值,socket发送缓存区的最大字节数;
根据实际测试,发送缓冲区的尺寸在默认情况下的全局设置是16384字节,即16k。
在测试系统上,发送缓存默认值是16k。
proc文件系统下的值和sysctl中的值都是全局值,应用程序可根据需要在程序中使用setsockopt()对某个socket的发送缓冲区尺寸进行单独修改,详见文章《深入浅出TCP中的send和recv》,不过这都是题外话。
 

2. 接收窗口(滑动窗口)

TCP连接建立之时的收端的初始接受窗口大小是14600,细节如图2所示(129是收端,130是发端)

图2

接收窗口是TCP中的滑动窗口,TCP的收端用这个接受窗口----win=14600,通知发端,我目前的接收能力是14600字节。
后续发送过程中,收端会不断的用ACK(ACK的全部作用请参照博文《TCP之ACK发送情景》)通知发端自己的接收窗口的大小状态,如图3,而发端发送数据的量,就根据这个接收窗口的大小来确定,发端不会发送超过收端接收能力的数据量。这样就起到了一个流量控制的的作用。

图3

图3说明
21,22两个包都是收端发给发端的ACK包
第21个包,收端确认收到的前7240个字节数据,7241的意思是期望收到的包从7241号开始,序号加了1.同时,接收窗口从最初的14656(如图2)经过慢启动阶段增加到了现在的29120。用来表明现在收端可以接收29120个字节的数据,而发端看到这个窗口通告,在没有收到新的ACK的时候,发端可以向收端发送29120字节这么多数据。
第22个包,收端确认收到的前8688个字节数据,并通告自己的接收窗口继续增长为32000这么大。

3. 单个TCP的负载量和MSS的关系

MSS在以太网上通常大小是1460字节,而我们在后续发送过程中的单个TCP包的最大数据承载量是1448字节,这二者的关系可以参考博文《TCP之1460MSS和1448负载》。

4. IP分片

引言

分片是分组交换的思想体现,也是IP协议解决的两个主要问题之一。在IP协议中的分片算法主要解决不同物理网络最大传输单元(MTU) 的不同造成的传输问题。但是分组在传输过程中不断地分片和重组会带来很大的工作量还会增加一些不安全的因素。我们将在这篇小论文中讨论IP分片的原因、原理、实现以及引起的安全问题。

一、什么是IP分片

IP分片是网络上传输IP报文的一种技术手段。IP协议在传输数据包时,将数据报文分为若干分片进行传输,并在目标系统中进行重组。这一过程称为分片(fragmentation)。

二、为什么要进行IP分片

每一种物理网络都会规定链路层数据帧的最大长度,称为链路层MTU(Maximum Transmission Unit).IP协议在传输数据包时,若IP数据报加上数据帧头部后长度大于MTU,则将数据报文分为若干分片进行传输,并在目标系统中进行重组。比如说,在以太网环境中可传输最大IP报文大小(MTU)为1500字节。如果要传输的数据帧大小超过1500字节,即IP数据报长度大于1472(1500-20-8=1472,普通数据报)字节,则需要分片之后进行传输。

三、IP分片原理及分析

分片和重新组装的过程对传输层是透明的,其原因是当IP数据报进行分片之后,只有当它到达目的站时,才可进行重新组装,且它是由目的端的IP层来完成的。分片之后的数据报根据需要也可以再次进行分片。

IP分片和完整IP报文差不多拥有相同的IP头,ID域对于每个分片都是一致的,这样才能在重新组装的时候识别出来自同一个IP报文的分片。在IP头里面,16位识别号唯一记录了一个IP包的ID,具有同一个ID的IP分片将会重新组装;而13位片偏移则记录了某IP片相对整个包的位置;而这两个表中间的3位标志则标志着该分片后面是否还有新的分片。这三个标志就组成了IP分片的所有信息(将在后面介绍),接受方就可以利用这些信息对IP数据进行重新组织。

1、标志字段的作用

标志字段在分片数据报中起了很大作用,在数据报分片时把它的值复制到每片中的标志字段的其中一个比特称作“不分片”位,用其中一个比特来表示“更多的片”。除了最后一片外,其他每个组成数据报的片都要把该比特置1。片偏移字段指的是该片偏移原始数据报开始处的位置。另外,当数据报被分片后,每个片的总长度值要改为该片的长度值。如果将标志字段的比特置1,则IP将不对数据报进行分片,若在某个中间路由器上需要对其分片,则仅仅把数据报丢弃并发送一个ICMP不可达差错报文给源主机。如果不是特殊需要,则不应该置1;最右比特置1表示该报文不是最后一个IP分片。故意发送部分IP分片而不是全部,则会导致目标主机总是等待分片消耗并占用系统资源。某些分片风暴攻击就是这种原理。这里以以太网为例,由于以太网传输电气方面的限制,每个以太网帧都有最小的大小64bytes最大不能超过1518bytes,抛去以太网帧的帧头(DMAC目的MAC地址48bit=6Bytes+SMAC源MAC地址48bit=6Bytes+Type域2bytes)14Bytes和帧尾CRC校验部分4Bytes,那么剩下承载上层协议的地方也就是Data域最大就只能有1500Bytes,这就是前面所说的MTU的值。这个也是网络层协议非常关心的地方,因为网络层的IP协议会根据这个值来决定是否把上层传达下来的数据进行分片。就好比一个盒子没法装下一大块面包,我们需要把面包切成片,装在多个盒子里面一样的道理。

下面是标志位在IP首部中的格式以及各个标志的意义:

Identification

R

DF

MF

Fragment Offset

   R:保留未用;DF:Don’t Fragment,“不分片”位,如果将这一比特置1,IP 层将不对数据报进行分片;MF:More Fragment,“更多的片”,除了最后一片外,其它每个组成数据报的片都要把比特置1;Fragment Offset:该片偏移原始数据包开始处的位置。偏移的字节数是该值乘以8。

2、MTU原理

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

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

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

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

3、MSS的原理

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

    当IP数据报被分片后,每一片都成为一个分组,具有自己的IP首部,并在选择路由时与其他分组独立。这样,当数据报的这些片到达目的端时有可能会失序,但是在IP首部中有足够的信息让接收端能正确组装这些数据报片。

    尽管IP分片过程看起来是透明的,但有一点让人不想使用它:即使只丢失一片数据也要重传整个数据报。因为IP层本身没有超时重传的机制——由更高层来负责超时和重传(TCP有超时和重传机制,但UDP没有。一些UDP应用程序本身也执行超时和重传)。当来自TCP报文段的某一片丢失后,TCP在超时后会重发整个TCP报文段,该报文段对应于一份IP数据报。没有办法只重传数据报中的一个数据报片。事实上,如果对数据报分片的是中间路由器,而不是起始端系统,那么起始端系统就无法知道数据报是如何被分片的。就这个原因,经常需要避免分片。

四、IP分片算法的原理

分片重组是IP层一个最重要的工作,其处理的主要思想:当数据包从一个网络A进入另一个网络B时,若原网络的数据包大于另一个网络或者接口的MTU长度,则需要进行分片(若设置DF为1,则丢弃,并回送ICMP不可达差错报文)。因而在IP数据包的报头有若干标识域注明分片包的共同标识号、分片的偏移量、是否最后一片及是否允许分片。传输途中的网关利用这些标识域进可能的再行分片,目有主机把收到的分片进行重组以恢重数据。因此,分片包在经过网络监测设备、安全设备、系统管理设备时,为了获取信息、处理数据,都必须完成数据包的分片或重组。

五、IP分片的安全问题

IP分片是在网络上传输IP报文时常采用的一种技术,但是其中存在一些安全隐患。Ping of Death, teardrop等攻击可能导致某些系统在重组IP分片的过程中宕机或者重新启动。一些IP分片攻击除了用于进行拒绝服务攻击之外,还常用于躲避防火墙或者网络入侵检测系统的一种手段。部分路由器或者基于网络的入侵检测系统(NIDS),由于IP分片重组能力的欠缺,导致无法进行正常的过滤或者检测。

介绍一下Tiny fragment 攻击:

所谓Tiny fragment攻击是指通过恶意操作,发送极小的分片来绕过包过滤系统或者入侵检测系统的一种攻击手段。攻击者通过恶意操作,可将TCP报头(通常为20字节)分布在2个分片中,这样一来,目的端口号可以包含在第二个分片中。对于包过滤设备或者入侵检测系统来说,首先通过判断目的端口号来采取允许/禁止措施。但是由于通过恶意分片使目的端口号位于第二个分片中,因此包过滤设备通过判断第一个分片,决定后续的分片是否允许通过。但是这些分片在目标主机上进行重组之后将形成各种攻击。通过这种方法可以迂回一些入侵检测系统及一些安全过滤系统。目前一些智能的包过滤设备直接丢掉报头中未包含端口信息的分片

猜你喜欢

转载自blog.csdn.net/ff900709/article/details/81939958