TCP/IP原理、基础以及在Linux上的实现(五)

日期: 2008-06-19 来源:TechTarget中国

IP在Linux上的实现

    如图6所示,Linux以分层的软件结构实现了TCP/IP协议。BSD套接字由一般性的套接字管理软件INET套接字层支持。INET套接字管理着基于IP的TCP或UDP协议端。在传输UDP数据报时,Linux不必关心数据报是否安全到达目的端。但对TCP数据报来说,Linux需要对数据报进行编号,数据报的源端和目的端需要协调工作,以便保证数据报不会丢失,或以错误的顺序发送。IP层包含的代码需要处理数据报的报头信息,并且必须将传入的数据报发送到TCP或 UDP两者中正确的一层处理。在IP层之下是Linux的网络设备层,其中包括以太网设备或PPP设备等。和Linux系统中的其它设备不同,网络设备并不总代表实际的物理设备,例如,回环设备就是一个纯软件设备。ARP协议提供地址解析功能,因此它处于IP层和网络设备层之间。


图6 Linux网络分层结构图


n

 图6 Linux网络分层结构图
 


    6.1 套接字缓冲区

    Linux利用套接字缓冲区在协议层和网络设备之间传送数据。Sk_buff包含了一些指针和长度信息,从而可让协议层以标准的函数或方法对应用程序的数据进行处理。如图7所示,每个sk_buff均包含一个数据块、四个数据指针以及两个长度字段。利用四个数据指针,各协议层可操纵和管理套接字缓冲区的数据,这四个指针的用途如下。


Head:指向内存中数据区的起始地址。Sk_buff和相关数据块在分配之后,该指针的值是固定的。


Data:指向协议数据的当前起始地址。该指针的值随当前拥有Sk_buff的协议层的变化而变化。


Tail:指向协议数据的当前结尾地址。和data指针一样,该指针的值也随当前拥有Sk_buff的协议层的变化而变化。


End:指向内存中数据区的结尾。和head指针一样,Sk_buff被分配之后,该指针的值也固定不变。


Sk_buff的两个长度字段,len和truesize,分别描述当前协议数据报的长度和数据缓冲区的实际长度。 


sk_buff结构图


 


6.2 接收IP数据报

当网络设备从网络上接收到数据报时,它必须将接收到的数据转换为sk_buff数据结构,然后将该结构添加到backlog队列中排队。当backlog队列变得很大时,接收到的sk_buff数据将会被丢弃。当新的sk_buff添加到backlog队列时,网络底层程序将被标志为就绪状态,从而可以让调度程序调度底层程序进行处理。


调度程序最终会运行网络的底层处理程序。这时,网络底层处理程序将处理任何等待传输的数据报,但在这之前,底层处理程序首先会处理sk_buff结构的backlog队列。底层处理程序必须确定将接收到的数据报传递到哪个协议层。


在Linux进行网络层的初始化时,每个协议要在ptype_all链表或ptype_base哈希表中添加packet_type数据结构以进行注册。Packet_type数据结构包含协议类型、指向网络设备的指针、指向协议的接收数据处理例程的指针等。Ptype_base是一个哈希表,其哈希函数以协议标识符为参数,内核通常利用该哈希表判断应当接受传入的网络数据报的协议。通过检查ptype_all链表和ptype_base哈希表,网络底层处理程序会复制新的sk_buff,最终,sk_buff会传递到一个或多个目标协议的处理例程。


6.3 发送IP 数据报

网络处理代码必须建立sk_buff来包含要传输的数据,并且在协议层之间传递数据时,需要添加不同的协议头和协议尾。


首先,IP协议需要决定要使用的网络设备,网络设备的选择依赖于数据报的最佳路由。对于只利用调制解调器和PPP协议连接的计算机来说,路由的选择比较容易,但是对于连接到以太网的计算机来说,路由的选择是比较复杂的。


对每个要传输的IP数据报,IP利用路由表解析目标IP地址的路由。对每个可从路由表中找到路由的目标IP地址,路由表返回一个rtable数据结构描述可使用的路由。这包括要使用的源地址、网络设备的device数据结构的地址以及预先建立的硬件头信息。该硬件头信息和网络设备相关,包含了源和目标的物理地址以及其它的介质信息。


6.4 数据报的分段与重组

当传输IP数据报时,IP从IP路由表中找到发送该IP数据报的网络设备,网络设备对应的device数据结构中包含由一个mtu字段,该字段描述最大的传输单元。如果设备的mtu小于等待发送的IP数据报的大小,就需要将该IP数据报划分为小的片断。每个片断由一个sk_buff代表,其中的IP头标记为数据报片断,以及该片断在IP数据报中的偏移。最后的数据报被标志为最后的IP片断。如果分段过程中IP不能分配sk_buff,则传输失败。


IP片断的接收较片断的发送更加复杂一些,因为IP片断可能以任意的顺序接收到,而在重组之前,必须接受到所有的片断。每次接收到IP数据报时,IP 要检查是否是一个分段数据报。当第一次接收到分段的消息时,IP建立一个新的ipq数据结构,并将它链接到由等待重组的IP片断形成的ipqueue链表中。随着其他IP片断的接收,IP找到正确的ipq数据结构,同时建立新的ipfrag数据结构描述该片断。每个ipq数据结构中包含有其源和目标IP地址、高层协议的标识符以及该IP帧的标识符,从而唯一描述了一个分段的IP接收帧。当所有的片断接收到之后,它们被组合成单一的sk_buff并传递到上一级协议层处理。如果定时器在所有的片断到达之前到期,ipq数据结构和ipfrag被丢弃,并假定消息已经在传输中丢失,这时,高层协议需要请求源主机重新发送丢失的信息。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

相关推荐