《TCP/IP详解 卷2:实现》 —2.6.4 m_pullup和IP的分片与重组
2.6.4 m_pullup和IP的分片与重组
m_pullup的第二个用途涉及IP和TCP的重组。假定IP接收到一个长度为296的分组,这个分组是一个大的IP数据报的一个分片。这个从设备驱动程序传到IP输入的mbuf看起来像我们在图2-16中所示的mbuf:296字节的数据存放在一个簇中。我们将这显示在图2-17中。
问题在于,IP的分片算法将各分片都存放在一个双向链表中,使用IP首部中的源与目标IP地址来存放向前与向后链表指针(当然,这两个IP地址要保存在这个链表的表头中,因为它们还要放回到重装的数据报中。我们在第10章讨论这个问题)。但是如果这个IP首部在一个簇中,如图2-17所示,这些链表指针会存放在这个簇中,并且当以后遍历链表时,指向IP首部的指针(即指向这个簇的起始的指针)不能被转换成指向mbuf的指针。这是我们在本节前面提到的问题:如果m_data指向一个簇时不能使用宏dtom,因为没有从簇指回mbuf的指针。IP分片不能如图2-17所示那样把链指针存储在簇中。
图2-17 一个长度为296的IP分片
为解决这个问题,当接收到一个分片时,若分片存放在一个簇中,IP分片例程总是调用m_pullup。它强行将20字节的IP首部放到它自己的mbuf中,代码如下:
图2-18所示的是在调用了m_pullup后得到的mbuf链表。m_pullup分配了一个新的mubf,挂在链表的前面,并从簇中取走40字节放入这个新的mbuf中。取40字节而不是仅要求的20字节,是为了保证以后在IP把数据报传给一个高层协议(例如ICMP、IGMP、UDP或TCP)时,高层协议能正确处理。采用不可思议的40(图7-17中的max_protohdr)是因为最大协议首部通常是一个20 字节的IP首部和一个20字节的TCP首部的组合(这假设其他协议族例如OSI协议并不编译到内核中)。
在图2-18中,IP分片算法在左边的mbuf中保存了一个指向IP首部的指针,并且可以用dtom将这个指针转换成一个指向mbuf本身的指针。
.4
- 点赞
- 收藏
- 关注作者
评论(0)