标签:accept 经验值 连接 便宜 ssi 有感 ack status possible
总之,Linux的ip_conntrack机制如果深究起来还真的看点,如果搞防火墙开发,实属不可不察也。下面就举几个例子。
if (set_reply)
set_bit(IPS_SEEN_REPLY_BIT, &ct->status);
这说明只要set_reply为真就会修改ct的一个状态位,而set_reply在ip_conntrack_in的resolve_normal_ct调用中就会被设置。//只要收到反向的包,就会设置IP_CT_ESTABLISHED,且把set_reply设置为1,然后返回到ip_conntrack_in的时候,就会导致ct->status的IPS_SEEN_REPLY_BIT的设置
if (DIRECTION(h) == IP_CT_DIR_REPLY) {
*ctinfo = IP_CT_ESTABLISHED + IP_CT_IS_REPLY;
/* Please set reply bit if this packet OK */
*set_reply = 1;
} else {
/* Once we‘ve had two way comms, always ESTABLISHED. */
//只要有IPS_SEEN_REPLY_BIT位被置位,那么就是IP_CT_ESTABLISHED
if (test_bit(IPS_SEEN_REPLY_BIT, &h->ctrack->status)) {
DEBUGP("ip_conntrack_in: normal packet for %p\n", h->ctrack);
*ctinfo = IP_CT_ESTABLISHED;
...
因此可见IP_CT_ESTABLISHED状态和具体的协议是无关的,对于TCP而言,所有SYN后面的包都会是IP_CT_ESTABLISHED状态。然而由于TCP本身拥有可以监控连接的状态,比如close-wait等,因此它在ip_conntrack中又有一些子状态,这个用于在适当的时候释放ip_conntrack数据结构,因此只要TCP的ip_conntrack的time-wait子状态到期,其ip_conntrack数据结构就会被当即释放,这一切正是因为TCP将其协议状态映射成了ip_conntrack的子状态,而这些子状态知道什么时候一个tcp流结束了。然而这一切对于UDP以及ICMP而言就没有这么幸运了,它们没有所谓的子状态,它们只能使用大胆的ip_conntrack状态。static int icmp_packet(struct ip_conntrack *ct,
const struct sk_buff *skb,
enum ip_conntrack_info ctinfo)
{
/* Try to delete connection immediately after all replies:
won‘t actually vanish as we still have skb, and del_timer
means this will only run once even if count hits zero twice
(theoretically possible with SMP) */
//只要有包返回,则递减icmp流的引用计数,如果是0,则释放ip_conntrack连接。实际上非SMP情况下在resolve_normal_ct中总会将找到的ip_conntrack的引用计数加1的,如果此时到达以下语句,即使icmp.count为0,调用了timeout.function,也不会释放ip_conntrack,进而在filter表中仍然可以使用ctsate或者state这些match,直到相关联的skb被free之后才会调用ip_conntrack_put进而将连接追踪的引用计数变为0从而删除之。
if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
//如果有同一个源到同一个目的的icmp包或者其返回包经过则递增icmp.count字段。
if (atomic_dec_and_test(&ct->proto.icmp.count)
&& del_timer(&ct->timeout))
ct->timeout.function((unsigned long)ct);
} else {
atomic_inc(&ct->proto.icmp.count);
ip_ct_refresh_acct(ct, ctinfo, skb, ip_ct_icmp_timeout);
}
return NF_ACCEPT;
}
该函数被ip_conntrack_in回调。实际上,对于每一个协议都有一个类似这样的回调函数,名为packet,该回调函数处理和协议相关的内容,比如对于TCP而言就是处理子状态。再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow
标签:accept 经验值 连接 便宜 ssi 有感 ack status possible
原文地址:https://www.cnblogs.com/ksiwnhiwhs/p/10390545.html