您的位置:首页 > 运维架构 > Linux

【转帖LINUX】netfilter中的conntrack内核阅读笔记(4)

2010-02-11 22:35 701 查看
2008-07-07 22:09
3,init_conntrack:
init_conntrack用于创建一个新的ip_conntrack,并对其进行初始化。
/*1,每一个连接包含两个tuple,original和reply,ip_ct_invert_tuple 根据传入的original tuple获取其reply tuple,其最终将调用所属协议的invert_tuple 完成处理*/
if (!ip_ct_invert_tuple(&repl_tuple, tuple, protocol)) {
DEBUGP("Can't invert tuple./n");
return NULL;
}
/*2,从cache中为conntrack分配内存,并进行通用的初始化,如初始化tuplehash、timeout和ct_general;如果当前连接数已达上限,则调用early_drop释放tuple所在hash链上的未应答项*/
conntrack = ip_conntrack_alloc(tuple, &repl_tuple);
/*3,调用所属协议的new函数,根据报文数据,初始化conntrack,和协议相关的私有处理,将放到对具体协议tcp分析时讨论*/
if (!protocol->new(conntrack, skb)) {
ip_conntrack_free(conntrack);
return NULL;
}
/*4,expect和helper均和动态协议相关,将在分析ftp协议时做重点介绍*/
exp = find_expectation(tuple);
if (exp) {

} else {
conntrack->helper = __ip_conntrack_helper_find(&repl_tuple);
CONNTRACK_STAT_INC(new);
}

write_unlock_bh(&ip_conntrack_lock);
if (exp) {

}
/*5,将original tuple放到unconfirmed链上??*/ list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed);

4,tuplehash_to_ctrack:
tuplehash_to_ctrack这个函数主要用来将全局连接表中获取的hashtuple转换成相应的ip_conntrack结构。它使用了container_of这个宏来完成处理的。container_of通过结构中某个成员的指针,来获取结构的指针。它的实现非常有趣:
/*1,将结构体强制在0地址展开,从而获取其member的偏移量*/
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
/*2,根据member的指针ptr,减去其相对偏移量,即获得了其宿主结构conntrack的指针*/
#define container_of(ptr, type, member) ({ /
const typeof( ((type *)0)->member ) *__mptr = (ptr); /
(type *)( (char *)__mptr - offsetof(type,member) );})

5,TCP
Ip层可以承载多种协议,不同的协议,在建立相应连接的状态表时,所需的信息和对信息的处理也是不同的,以下我们将以tcp协议为例阐述具体协议的处理过程。
首先,在ip_conntrack_in的步骤3中,当我们确定了具体承载的协议后,需要调用相关的error函数,对报文的有效性进行验证,该函数为ip_conntrack_protocol_tcp.c中的tcp_error函数,该函数主要检查了tcp报文头的完整性,校验和的正确性以及flag的有效性。
在ip_conntrack_in步骤4的处理过程中,首先通过ip_ct_get_tuple(resolve_normal_ct step1)函数调用tcp_pkt_to_tuple将报文中的相关信息转化成一个tcp连接所需的tuple。之后根据这个tuple查找全局连接表,获取相应的状态表(resolve_normal_ct step2);对于新建连接则调用tcp_new建立并初始化状态表(init_conntrack)。Filter为Tcp的连接建立状态表的过程分为两类;一种filter知道连接的建立过程,它从连接的第一个syn报文开始,就记录连接的状态;另一种是filter不知道连接何时建立的,filter开始记录连接的状态时,连接早已建立成功,filter不知道连接的过去,例如filter发生重启,丢失了所有原有的连接状态信息。针对后一种情况,系统通过全局变量ip_ct_tcp_loose来确定是否支持,对此种情况后续章节会有专门的介绍。tcp_new针对此两种情况分别进行了设置。
在ip_conntrack_in步骤5,最终调用tcp_packet对报文进行处理,并更新相应的连接状态。在这里最为重要的是通过tcp_in_window来判别报文的有效性。在介绍该函数之前,先来了解一些tcp filter的知识。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: