网络层是TCP/IP层次模型的第二层,主要功能是路径选择、拥塞控制和网际互连。IP协议是网络层最主要的协议,提供路由功能,并对传输层的数据进行重新组装,以适应不同网络对数据包大小的要求,实现两个节点间的通信。协议有IPv4和IPv6两个版本,现在最通用的是IPv4。

IP和链路层之间传送的数据单元被称作分组,分组既可以是一个IP数据报,也可以是数据报的一个分片。封装IP分组的一个过程就是添加IP首部,其格式如下(图片来自网络)。
Image Title

  • 版本:4位,IP协议版本。值一般为4,即采用IPv4版本。

  • 首部长度:4位,IP首部长度,4个字节为单位。首部包含可选项,是变长数据,取值范围为5-15,能表示20字节-60字节。

  • DSCP:6位,区分服务代码点。

  • ECN:2位,显式拥塞通知。

  • 总长度:2个字节,IP分组的长度。

  • 标识:2个字节,IP分组标识。由于IP是无连接服务,标识并非序号。当IP数据报长度大于MTU时,会进行分片,同一数据报的所有分片标识相同,以在接收端重新组装成一个数据报。

  • 标志:3位。第1位未使用。第2位DF禁止分片,需要分片的数据报会被丢弃,并发送一个ICMP差错报文给起始端。第3位MF更多分片,当对数据报进行分片时,最后一个分片置0,其余分片置1。

  • 片偏移:13位,8个字节为单位。表示数据报被分片后,该片数据在原数据报中的相对位置。

  • TTL:1个字节,IP分组在网络上的存活时间。每经过一个路由器该值减1,为0时则丢弃。

  • 协议类型:1个字节,上层协议类型。常见值如1(ICMP)、6(TCP)、17(UDP)等。

  • 首部校验和:2个字节,只计算首部。

  • 源IP地址:4个字节,发送端IP地址。

  • 目的IP地址:4个字节,接收端IP地址。

  • 可选字段:0-40字节,使用较少,暂不赘述。

依然以tcpdump捕获到的TCP三次握手数据包为例。
Image Title

观察第一个数据包的前20字节。

  • 4500:4表示IPv4版本,5表示首部长度为20(5*4)字节,没有可选项,00表示无区分服务和显式拥塞通知。

  • 0034:表示IP分组长度为52(3*16+4)字节,则数据域长度为32字节。

  • 1150:标识。

  • 4000:前3位010,DF置1表示禁止分片,后13位为0表示片偏移为0。

  • 8006:80表示TTL为128(8*16),06表示上层协议是TCP。

  • 6136:检验和。仅计算首部。

  • c0a8 0305:源IP地址是192.168.3.5。

  • c0a8 03e8:目的IP地址是192.168.3.232。

上篇文章中提到,采用Ethernet II的以太网MTU是1500字节,所以IP分组长度不能大于1500字节。IP首部20字节,则IP数据域长度最大1480字节。如果传输层数据包长度大于此值,则需要分片。

同时,标准要求主机可以接收最小576字节的IP数据报。因此,如果数据需要传给未知的主机或经过未知的网络,并希望不会因为大小的原因而被丢弃,那么IP分组长度不应该大于576字节,否则需要分片。

分片过程中,协议层会对IP数据报进行合适的分割,使每片都不大于MTU。IP数据报的标识会被复制到每个分片中,最后一个分片的MF置0,其他分片置1,片偏移里保存每个分片数据相对于原数据以8个字节为单位的偏移值,这意味着除最后一个分片外,其他分片数据长度都是8字节的整数倍。

分片不只发生在发送端,在传输过程中,IP分组也可能被重新分片,由DF标志位决定。

接收端收到IP分片时,会检查MF标志位是否是0即最后一个分片,如果是,则根据分片偏移量计算各个分片在原始数据报中的位置并进行重组,否则等待所有分片到达后再进行重组。

不难看出,分片可能带来以下问题。

  • 资源消耗:分片和重组会消耗一定的CPU等资源,如果存在大量的分片报文的话,可能会造成较为严重的资源消耗;分片对接收方内存资源的消耗较多,因为接收端要为接收到的每个分片分配内存空间,以便于最后一个分片到达后完成重组。

  • 重传问题:如果某个分片在网络传输过程中丢失,那么接收端将无法完成重组,如果应用进程要求重传的话,发送端必须重传整个数据报的所有分片而不是仅重传被丢弃的那个,这会给端系统和网络带来额外的消耗。