【转帖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的知识。 |
相关文章推荐
- 【转帖LINUX】netfilter中的conntrack内核阅读笔记(1)
- 【转帖LINUX】netfilter中的conntrack内核阅读笔记(2)
- 【转帖LINUX】netfilter中的conntrack内核阅读笔记(3)
- 【转帖LINUX】netfilter中的conntrack内核阅读笔记(5)
- (转载)Linux内核网络设备操作部分阅读笔记收藏
- Linux 2.6 内核阅读笔记 内存管理
- Linux 2.6 内核阅读笔记 进程
- LINUX0.11内核阅读笔记 (2)
- (原创)Linux内核网络设备操作部分阅读笔记
- Linux网管笔记(17)阅读Linux的内核源码
- (转载)Linux内核网络设备操作部分阅读笔记
- LINUX0.11内核阅读笔记
- Linux 内核WorkQueue阅读笔记
- LINUX0.11内核阅读笔记
- LINUX0.11内核阅读笔记
- LINUX0.11内核阅读笔记
- Linux 2.6 内核阅读笔记 信号
- Linux 2.6 内核阅读笔记 内核同步
- Linux 2.6 内核阅读笔记 中断和异常
- Linux内核网络设备操作部分阅读笔记