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

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的知识。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值