在这个系列文章中,我自己将尝试着分析Linux kernel2.6下面的中的网络部分的源代码,主要是TCP/IP部分,只是记录自己的学习经历,如果你感兴趣,不妨说出你的理解。
这是第一部分,主要分析一下 TCP/IP相关协议以及实现网络协议时kennel常用的数据结构,提供一些基础知识。注意,虽然分析的主要是TCP/IP族,但不可避免提及其它的一些协议,因为TCP/IP族只是网络协议的一个组成。
TCP/IP协议的分层
在TCP/IP协议的学习中,很多人对TCP/IP协议的分层不是很理解,其实,可以用一句话概括分层的原因--“各司其职”
。TCP/IP中的主要协议,可以用下面这个图进行一个简单的说明。(下图没有包含SCTP,它属于Transport Layer,但在2.6的kernel是支持的)总的来说:Data-link layer是处理硬件相关的问题,在实现上多是和硬件驱动相关的代码;而Network layer则在Data-link layer的基础上提供数据的投寄,比如我们常说的IP协议,提供转发(将Packet发送到其它host)或者象上层传递(以本机为目的地的 Packet);Transport layer在IP协议的基础上更进一步的对数据的交互提供控制,比如TCP提供可靠的双向连接;Application layer是我们的网络程序,通常实现一个具体的功能。分层的关键点在于:Network layer的IP协议的特点是:unreliable(不可靠), connectionless(无连接)的,原因是IP协议只是尽力去把数据交付给目的地,它并不提供其它诸如安全性,可靠性等保证。在 Transport layer提供其它的保证,比如TCP提供了可靠性等保证,而UDP则在IP协议的上面增加了对给定主机上的多个目的地址进行区别的能力。好了,下面开始正式进入主题。
在下面,我将首先分析几个重要的数据结构,主要是sk_buff,net_device,sock。好了,喝一口水,放下杯子,Let‘s Go!
sk_buff (Socket Buffer)结构
在网络相关代码中,一个基本的问题就是内存的管理,这些内存管理的基本结构都是经过精心设计的,例如,在BSD的代码中的mbuf结构,而Linux中则是 sk_buff(Socket Buffer)。在Stevens的巨著TCP/IP Illustrated V2中描述mbuf所面临的问题时,很好的说明了网络Code相关的内存管理的基本观点。关键点是:sk_buff是被不同的Layer所使用,是层层传递的(从Layer1->Layer4或者反向)。
sk_buff(include/linux/skbuff.h) 的最初的设计者是Alan Cox(大名鼎鼎的Hacker哦,网络部分的Code经常看到其大名),他在网上发表过一篇关于sk_buff设计相关的文章,可以去看看(当然,我是看过的,呵呵,要是不愿意啃e文,就看我的文章好了
)。下面我将对sk_buff结构进行分析。这个结构大小居中,一般来说,这种结构的组织是有一定逻辑的,它可以分为:
分层信息:自然,是根据上面所说的四层结构 packet的一般信息 指定特征描述 相关管理函数(callback function的形式) 了解面向对象(OO)的人一定会说,呵呵,不就是个类(Class)么!不错,这样理解没什么问题,毕竟,面向对象(OO)是思想,与语言关系并不唯一。
struct sk_buff { struct sk_buff_head *list; //指向链表的头
/* These two members must be first. */
struct sk_buff *next; //这两个变量让sk_buff
struct sk_buff *prev; //构成双向的链表
struct sock *sk; //指向创建这个sk_buff的socket
struct timeval stamp; //该packet到达的时间(以jiffies为单位)
struct net_device *dev; //incoming/outcoming 的设备
struct net_device *input_dev; //到达的设备
struct net_device *real_dev; //真实使用的设备