⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nf_conntrack_proto_tcp.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;	timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans		  && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans		  ? nf_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];	write_unlock_bh(&tcp_lock);	nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);	if (new_state != old_state)		nf_conntrack_event_cache(IPCT_PROTOINFO, skb);	if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {		/* If only reply is a RST, we can consider ourselves not to		   have an established connection: this is a fairly common		   problem case, so we can delete the conntrack		   immediately.  --RR */		if (th->rst) {			if (del_timer(&conntrack->timeout))				conntrack->timeout.function((unsigned long)							    conntrack);			return NF_ACCEPT;		}	} else if (!test_bit(IPS_ASSURED_BIT, &conntrack->status)		   && (old_state == TCP_CONNTRACK_SYN_RECV		       || old_state == TCP_CONNTRACK_ESTABLISHED)		   && new_state == TCP_CONNTRACK_ESTABLISHED) {		/* Set ASSURED if we see see valid ack in ESTABLISHED		   after SYN_RECV or a valid answer for a picked up		   connection. */		set_bit(IPS_ASSURED_BIT, &conntrack->status);		nf_conntrack_event_cache(IPCT_STATUS, skb);	}	nf_ct_refresh_acct(conntrack, ctinfo, skb, timeout);	return NF_ACCEPT;}/* Called when a new connection for this protocol found. */static int tcp_new(struct nf_conn *conntrack,		   const struct sk_buff *skb,		   unsigned int dataoff){	enum tcp_conntrack new_state;	struct tcphdr *th, _tcph;	struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[0];	struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[1];	th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);	BUG_ON(th == NULL);	/* Don't need lock here: this conntrack not in circulation yet */	new_state		= tcp_conntracks[0][get_conntrack_index(th)]		[TCP_CONNTRACK_NONE];	/* Invalid: delete conntrack */	if (new_state >= TCP_CONNTRACK_MAX) {		pr_debug("nf_ct_tcp: invalid new deleting.\n");		return 0;	}	if (new_state == TCP_CONNTRACK_SYN_SENT) {		/* SYN packet */		conntrack->proto.tcp.seen[0].td_end =			segment_seq_plus_len(ntohl(th->seq), skb->len,					     dataoff, th);		conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);		if (conntrack->proto.tcp.seen[0].td_maxwin == 0)			conntrack->proto.tcp.seen[0].td_maxwin = 1;		conntrack->proto.tcp.seen[0].td_maxend =			conntrack->proto.tcp.seen[0].td_end;		tcp_options(skb, dataoff, th, &conntrack->proto.tcp.seen[0]);		conntrack->proto.tcp.seen[1].flags = 0;	} else if (nf_ct_tcp_loose == 0) {		/* Don't try to pick up connections. */		return 0;	} else {		/*		 * We are in the middle of a connection,		 * its history is lost for us.		 * Let's try to use the data from the packet.		 */		conntrack->proto.tcp.seen[0].td_end =			segment_seq_plus_len(ntohl(th->seq), skb->len,					     dataoff, th);		conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);		if (conntrack->proto.tcp.seen[0].td_maxwin == 0)			conntrack->proto.tcp.seen[0].td_maxwin = 1;		conntrack->proto.tcp.seen[0].td_maxend =			conntrack->proto.tcp.seen[0].td_end +			conntrack->proto.tcp.seen[0].td_maxwin;		conntrack->proto.tcp.seen[0].td_scale = 0;		/* We assume SACK and liberal window checking to handle		 * window scaling */		conntrack->proto.tcp.seen[0].flags =		conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM |						     IP_CT_TCP_FLAG_BE_LIBERAL;	}	conntrack->proto.tcp.seen[1].td_end = 0;	conntrack->proto.tcp.seen[1].td_maxend = 0;	conntrack->proto.tcp.seen[1].td_maxwin = 1;	conntrack->proto.tcp.seen[1].td_scale = 0;	/* tcp_packet will set them */	conntrack->proto.tcp.state = TCP_CONNTRACK_NONE;	conntrack->proto.tcp.last_index = TCP_NONE_SET;	pr_debug("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "		 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",		 sender->td_end, sender->td_maxend, sender->td_maxwin,		 sender->td_scale,		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,		 receiver->td_scale);	return 1;}#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)#include <linux/netfilter/nfnetlink.h>#include <linux/netfilter/nfnetlink_conntrack.h>static int tcp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,			 const struct nf_conn *ct){	struct nlattr *nest_parms;	struct nf_ct_tcp_flags tmp = {};	read_lock_bh(&tcp_lock);	nest_parms = nla_nest_start(skb, CTA_PROTOINFO_TCP | NLA_F_NESTED);	if (!nest_parms)		goto nla_put_failure;	NLA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t),		&ct->proto.tcp.state);	NLA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, sizeof(u_int8_t),		&ct->proto.tcp.seen[0].td_scale);	NLA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY, sizeof(u_int8_t),		&ct->proto.tcp.seen[1].td_scale);	tmp.flags = ct->proto.tcp.seen[0].flags;	NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,		sizeof(struct nf_ct_tcp_flags), &tmp);	tmp.flags = ct->proto.tcp.seen[1].flags;	NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY,		sizeof(struct nf_ct_tcp_flags), &tmp);	read_unlock_bh(&tcp_lock);	nla_nest_end(skb, nest_parms);	return 0;nla_put_failure:	read_unlock_bh(&tcp_lock);	return -1;}static const struct nla_policy tcp_nla_policy[CTA_PROTOINFO_TCP_MAX+1] = {	[CTA_PROTOINFO_TCP_STATE]	    = { .type = NLA_U8 },	[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] = { .type = NLA_U8 },	[CTA_PROTOINFO_TCP_WSCALE_REPLY]    = { .type = NLA_U8 },	[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]  = { .len = sizeof(struct nf_ct_tcp_flags) },	[CTA_PROTOINFO_TCP_FLAGS_REPLY]	    = { .len =  sizeof(struct nf_ct_tcp_flags) },};static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct){	struct nlattr *attr = cda[CTA_PROTOINFO_TCP];	struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1];	int err;	/* updates could not contain anything about the private	 * protocol info, in that case skip the parsing */	if (!attr)		return 0;	err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr, tcp_nla_policy);	if (err < 0)		return err;	if (!tb[CTA_PROTOINFO_TCP_STATE])		return -EINVAL;	write_lock_bh(&tcp_lock);	ct->proto.tcp.state =		*(u_int8_t *)nla_data(tb[CTA_PROTOINFO_TCP_STATE]);	if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) {		struct nf_ct_tcp_flags *attr =			nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]);		ct->proto.tcp.seen[0].flags &= ~attr->mask;		ct->proto.tcp.seen[0].flags |= attr->flags & attr->mask;	}	if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]) {		struct nf_ct_tcp_flags *attr =			nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]);		ct->proto.tcp.seen[1].flags &= ~attr->mask;		ct->proto.tcp.seen[1].flags |= attr->flags & attr->mask;	}	if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] &&	    tb[CTA_PROTOINFO_TCP_WSCALE_REPLY] &&	    ct->proto.tcp.seen[0].flags & IP_CT_TCP_FLAG_WINDOW_SCALE &&	    ct->proto.tcp.seen[1].flags & IP_CT_TCP_FLAG_WINDOW_SCALE) {		ct->proto.tcp.seen[0].td_scale = *(u_int8_t *)			nla_data(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]);		ct->proto.tcp.seen[1].td_scale = *(u_int8_t *)			nla_data(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]);	}	write_unlock_bh(&tcp_lock);	return 0;}#endif#ifdef CONFIG_SYSCTLstatic unsigned int tcp_sysctl_table_users;static struct ctl_table_header *tcp_sysctl_header;static struct ctl_table tcp_sysctl_table[] = {	{		.procname	= "nf_conntrack_tcp_timeout_syn_sent",		.data		= &nf_ct_tcp_timeout_syn_sent,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "nf_conntrack_tcp_timeout_syn_recv",		.data		= &nf_ct_tcp_timeout_syn_recv,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "nf_conntrack_tcp_timeout_established",		.data		= &nf_ct_tcp_timeout_established,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "nf_conntrack_tcp_timeout_fin_wait",		.data		= &nf_ct_tcp_timeout_fin_wait,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "nf_conntrack_tcp_timeout_close_wait",		.data		= &nf_ct_tcp_timeout_close_wait,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "nf_conntrack_tcp_timeout_last_ack",		.data		= &nf_ct_tcp_timeout_last_ack,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "nf_conntrack_tcp_timeout_time_wait",		.data		= &nf_ct_tcp_timeout_time_wait,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "nf_conntrack_tcp_timeout_close",		.data		= &nf_ct_tcp_timeout_close,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "nf_conntrack_tcp_timeout_max_retrans",		.data		= &nf_ct_tcp_timeout_max_retrans,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_NF_CONNTRACK_TCP_LOOSE,		.procname	= "nf_conntrack_tcp_loose",		.data		= &nf_ct_tcp_loose,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},	{		.ctl_name	= NET_NF_CONNTRACK_TCP_BE_LIBERAL,		.procname       = "nf_conntrack_tcp_be_liberal",		.data           = &nf_ct_tcp_be_liberal,		.maxlen         = sizeof(unsigned int),		.mode           = 0644,		.proc_handler   = &proc_dointvec,	},	{		.ctl_name	= NET_NF_CONNTRACK_TCP_MAX_RETRANS,		.procname	= "nf_conntrack_tcp_max_retrans",		.data		= &nf_ct_tcp_max_retrans,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},	{		.ctl_name	= 0	}};#ifdef CONFIG_NF_CONNTRACK_PROC_COMPATstatic struct ctl_table tcp_compat_sysctl_table[] = {	{		.procname	= "ip_conntrack_tcp_timeout_syn_sent",		.data		= &nf_ct_tcp_timeout_syn_sent,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "ip_conntrack_tcp_timeout_syn_recv",		.data		= &nf_ct_tcp_timeout_syn_recv,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "ip_conntrack_tcp_timeout_established",		.data		= &nf_ct_tcp_timeout_established,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "ip_conntrack_tcp_timeout_fin_wait",		.data		= &nf_ct_tcp_timeout_fin_wait,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "ip_conntrack_tcp_timeout_close_wait",		.data		= &nf_ct_tcp_timeout_close_wait,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "ip_conntrack_tcp_timeout_last_ack",		.data		= &nf_ct_tcp_timeout_last_ack,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "ip_conntrack_tcp_timeout_time_wait",		.data		= &nf_ct_tcp_timeout_time_wait,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "ip_conntrack_tcp_timeout_close",		.data		= &nf_ct_tcp_timeout_close,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.procname	= "ip_conntrack_tcp_timeout_max_retrans",		.data		= &nf_ct_tcp_timeout_max_retrans,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_LOOSE,		.procname	= "ip_conntrack_tcp_loose",		.data		= &nf_ct_tcp_loose,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},	{		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL,		.procname	= "ip_conntrack_tcp_be_liberal",		.data		= &nf_ct_tcp_be_liberal,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},	{		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS,		.procname	= "ip_conntrack_tcp_max_retrans",		.data		= &nf_ct_tcp_max_retrans,		.maxlen		= sizeof(unsigned int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},	{		.ctl_name	= 0	}};#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */#endif /* CONFIG_SYSCTL */struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly ={	.l3proto		= PF_INET,	.l4proto 		= IPPROTO_TCP,	.name 			= "tcp",	.pkt_to_tuple 		= tcp_pkt_to_tuple,	.invert_tuple 		= tcp_invert_tuple,	.print_tuple 		= tcp_print_tuple,	.print_conntrack 	= tcp_print_conntrack,	.packet 		= tcp_packet,	.new 			= tcp_new,	.error			= tcp_error,#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)	.to_nlattr		= tcp_to_nlattr,	.from_nlattr		= nlattr_to_tcp,	.tuple_to_nlattr	= nf_ct_port_tuple_to_nlattr,	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,	.nla_policy		= nf_ct_port_nla_policy,#endif#ifdef CONFIG_SYSCTL	.ctl_table_users	= &tcp_sysctl_table_users,	.ctl_table_header	= &tcp_sysctl_header,	.ctl_table		= tcp_sysctl_table,#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT	.ctl_compat_table	= tcp_compat_sysctl_table,#endif#endif};EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4);struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly ={	.l3proto		= PF_INET6,	.l4proto 		= IPPROTO_TCP,	.name 			= "tcp",	.pkt_to_tuple 		= tcp_pkt_to_tuple,	.invert_tuple 		= tcp_invert_tuple,	.print_tuple 		= tcp_print_tuple,	.print_conntrack 	= tcp_print_conntrack,	.packet 		= tcp_packet,	.new 			= tcp_new,	.error			= tcp_error,#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)	.to_nlattr		= tcp_to_nlattr,	.from_nlattr		= nlattr_to_tcp,	.tuple_to_nlattr	= nf_ct_port_tuple_to_nlattr,	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,	.nla_policy		= nf_ct_port_nla_policy,#endif#ifdef CONFIG_SYSCTL	.ctl_table_users	= &tcp_sysctl_table_users,	.ctl_table_header	= &tcp_sysctl_header,	.ctl_table		= tcp_sysctl_table,#endif};EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -