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

📄 tcpsp_conn.c

📁 在传输层实现了资源的负载平衡 实现了集群
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * tcpsp_conn.c: connection tracking for tcp splicing * * Version:     $Id: tcpsp_conn.c,v 1.6 2003/12/01 09:44:51 wensong Exp $ * * Authors:     Wensong Zhang <wensong@linux-vs.org> * *              This program is free software; you can redistribute it and/or *              modify it under the terms of the GNU General Public License *              as published by the Free Software Foundation; either version *              2 of the License, or (at your option) any later version. * * Changes: * */#include <linux/config.h>#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/vmalloc.h>#include <linux/ip.h>#include <linux/tcp.h>                  /* for tcphdr */#include <linux/in.h>#include <linux/proc_fs.h>              /* for proc_net_* */#include <asm/softirq.h>                /* for local_bh_* */#include <net/ip.h>#include <net/tcp.h>                    /* for csum_tcpudp_magic */#include <net/udp.h>#include <net/icmp.h>                   /* for icmp_send */#include <net/route.h>                  /* for ip_route_output */#include <linux/socket.h>#include <linux/netfilter.h>#include <linux/netfilter_ipv4.h>#include "tcpsp.h"//#include <net/tcpsp.h>EXPORT_SYMBOL(tcpsp_conn_new);/*  SLAB cache for tcpsp connections */static kmem_cache_t *tcpsp_conn_cachep;/* tcpsp onnection hash tables */#define TCPSP_NTABLES		2static struct list_head *tcpsp_conn_tab1;static struct list_head *tcpsp_conn_tab2;static rwlock_t tcpsp_conn_lock = RW_LOCK_UNLOCKED;/*  counter for current tcpsp connections */static atomic_t tcpsp_conn_count = ATOMIC_INIT(0);/* *	Returns hash value for tcpsp connection entry */static inline unsignedtcpsp_conn_hash_key(__u32 addr, __u16 port){	unsigned addrh = ntohl(addr);	return (addrh^(addrh>>TCPSP_CONN_TAB_BITS)^ntohs(port))		& TCPSP_CONN_TAB_MASK;}/* *	Hashes tcpsp_conn in tcpsp_conn_tabs by <addr,port>. *	returns bool success. */static int tcpsp_conn_hash(struct tcpsp_conn *cp){	unsigned hash;	if (cp->flags & TCPSP_CONN_F_HASHED) {		TCPSP_ERR("tcpsp_conn_hash(): request for already hashed, "			  "called from %p\n", __builtin_return_address(0));		return 0;	}	write_lock(&tcpsp_conn_lock);	hash = tcpsp_conn_hash_key(cp->conn[0].raddr, cp->conn[0].rport);	list_add(&cp->f_list, &tcpsp_conn_tab1[hash]);	hash = tcpsp_conn_hash_key(cp->conn[1].laddr, cp->conn[1].lport);	list_add(&cp->s_list, &tcpsp_conn_tab2[hash]);	cp->flags |= TCPSP_CONN_F_HASHED;	atomic_add(TCPSP_NTABLES, &cp->refcnt);	write_unlock(&tcpsp_conn_lock);	return 1;}/* *	UNhashes tcpsp_conn from tcpsp_conn_tabs. *	returns bool success. */static int tcpsp_conn_unhash(struct tcpsp_conn *cp){	if (!(cp->flags & TCPSP_CONN_F_HASHED)) {		TCPSP_ERR("tcpsp_conn_unhash(): request for unhash flagged, "			  "called from %p\n", __builtin_return_address(0));		return 0;	}	write_lock(&tcpsp_conn_lock);	list_del(&cp->f_list);	list_del(&cp->s_list);	cp->flags &= ~TCPSP_CONN_F_HASHED;	atomic_sub(TCPSP_NTABLES, &cp->refcnt);	write_unlock(&tcpsp_conn_lock);	return 1;}struct tcpsp_conn *tcpsp_conn_get(__u32 saddr, __u16 sport, __u32 daddr, __u16 dport, int *dir){	unsigned hash;	struct list_head *e;	struct tcpsp_conn *cp;	struct conn_tuple *t;	read_lock(&tcpsp_conn_lock);	hash = tcpsp_conn_hash_key(saddr, sport);	list_for_each (e, &tcpsp_conn_tab1[hash]) {		cp = list_entry(e, struct tcpsp_conn, f_list);		t = &cp->conn[0];		if (saddr == t->raddr && sport == t->rport &&		    dport == t->lport && daddr == t->laddr) {			/* HIT */			*dir = FROM_FIRST_CONN;			atomic_inc(&cp->refcnt);			read_unlock(&tcpsp_conn_lock);			return cp;		}	}	hash = tcpsp_conn_hash_key(daddr, dport);	list_for_each (e, &tcpsp_conn_tab2[hash]) {		cp = list_entry(e, struct tcpsp_conn, s_list);		t = &cp->conn[1];		if (dport == t->lport && daddr == t->laddr &&		    saddr == t->raddr && sport == t->rport) {			/* HIT */			*dir = FROM_SECOND_CONN;			atomic_inc(&cp->refcnt);			read_unlock(&tcpsp_conn_lock);			return cp;		}	}	read_unlock(&tcpsp_conn_lock);	return NULL;}/* *      Put back the conn and restart its timer with its timeout */void tcpsp_conn_put(struct tcpsp_conn *cp){	/* reset it expire in its timeout */	mod_timer(&cp->timer, jiffies+cp->timeout);	__tcpsp_conn_put(cp);}/* *	Timeout table[state] */struct tcpsp_timeout_table tcpsp_timeout_tbl = {	ATOMIC_INIT(0),	/* refcnt */	0,		/* scale  */	{		[TCPSP_S_NONE]          =	3*60*HZ,		[TCPSP_S_ESTABLISHED]	=	15*60*HZ,		[TCPSP_S_SYN_SENT]	=	2*60*HZ,		[TCPSP_S_SYN_RECV]	=	1*60*HZ,		[TCPSP_S_FIN_WAIT]	=	2*60*HZ,		[TCPSP_S_TIME_WAIT]	=	2*60*HZ,		[TCPSP_S_CLOSE]         =	10*HZ,		[TCPSP_S_CLOSE_WAIT]	=	60*HZ,		[TCPSP_S_LAST_ACK]	=	30*HZ,		[TCPSP_S_LISTEN]	=	2*60*HZ,		[TCPSP_S_SYNACK]	=	120*HZ,		[TCPSP_S_LAST]          =	2*HZ,	},	/* timeout */};static const char * state_name_table[TCPSP_S_LAST+1] = {	[TCPSP_S_NONE]          =	"NONE",	[TCPSP_S_ESTABLISHED]	=	"ESTABLISHED",	[TCPSP_S_SYN_SENT]	=	"SYN_SENT",	[TCPSP_S_SYN_RECV]	=	"SYN_RECV",	[TCPSP_S_FIN_WAIT]	=	"FIN_WAIT",	[TCPSP_S_TIME_WAIT]	=	"TIME_WAIT",	[TCPSP_S_CLOSE]         =	"CLOSE",	[TCPSP_S_CLOSE_WAIT]	=	"CLOSE_WAIT",	[TCPSP_S_LAST_ACK]	=	"LAST_ACK",	[TCPSP_S_LISTEN]	=	"LISTEN",	[TCPSP_S_SYNACK]	=	"SYNACK",	[TCPSP_S_LAST]          =	"BUG!",};#define sNO TCPSP_S_NONE#define sES TCPSP_S_ESTABLISHED#define sSS TCPSP_S_SYN_SENT#define sSR TCPSP_S_SYN_RECV#define sFW TCPSP_S_FIN_WAIT#define sTW TCPSP_S_TIME_WAIT#define sCL TCPSP_S_CLOSE#define sCW TCPSP_S_CLOSE_WAIT#define sLA TCPSP_S_LAST_ACK#define sLI TCPSP_S_LISTEN#define sSA TCPSP_S_SYNACKstruct tcpsp_states_t {	int next_state[TCPSP_S_LAST];	/* should be _LAST_TCP */};const char * tcpsp_state_name(int state){	if (state >= TCPSP_S_LAST)		return "ERR!";	return state_name_table[state] ? state_name_table[state] : "?";}static struct tcpsp_states_t tcpsp_states[] = {/*	INPUT *//*        sNO, sES, sSS, sSR, sFW, sTW, sCL, sCW, sLA, sLI, sSA	*//*syn*/ {{sSR, sES, sES, sSR, sSR, sSR, sSR, sSR, sSR, sSR, sSR }},/*fin*/ {{sCL, sCW, sSS, sTW, sTW, sTW, sCL, sCW, sLA, sLI, sTW }},/*ack*/ {{sCL, sES, sSS, sES, sFW, sTW, sCL, sCW, sCL, sLI, sES }},/*rst*/ {{sCL, sCL, sCL, sSR, sCL, sCL, sCL, sCL, sLA, sLI, sSR }},/*	OUTPUT *//*        sNO, sES, sSS, sSR, sFW, sTW, sCL, sCW, sLA, sLI, sSA	*//*syn*/ {{sSS, sES, sSS, sSR, sSS, sSS, sSS, sSS, sSS, sLI, sSR }},/*fin*/ {{sTW, sFW, sSS, sTW, sFW, sTW, sCL, sTW, sLA, sLI, sTW }},/*ack*/ {{sES, sES, sSS, sES, sFW, sTW, sCL, sCW, sLA, sES, sES }},/*rst*/ {{sCL, sCL, sSS, sCL, sCL, sTW, sCL, sCL, sCL, sCL, sCL }},};static struct tcpsp_states_t *tcpsp_state_table = tcpsp_states;static inline int tcp_state_idx(struct tcphdr *th, int state_off){	/*	 *	[0-3]: input states, [4-7]: output, [8-11] input only states.	 */	if (th->rst)		return state_off+3;	if (th->syn)		return state_off+0;	if (th->fin)		return state_off+1;	if (th->ack)		return state_off+2;	return -1;}static inline int set_state_timeout(struct tcpsp_conn *cp, int state){	struct tcpsp_timeout_table *tt = cp->timeout_table;	/*	 *	Use default timeout table if no specific for this entry	 */	if (!tt)		tt = &tcpsp_timeout_tbl;	cp->timeout = tt->timeout[cp->state=state];	if (tt->scale) {		int scale = tt->scale;		if (scale<0)			cp->timeout >>= -scale;		else if (scale > 0)			cp->timeout <<= scale;	}	return state;}static inline intset_state(struct tcpsp_conn *cp, int state_off, struct tcphdr *th){	int state_idx;	int new_state = TCPSP_S_CLOSE;	if ((state_idx = tcp_state_idx(th, state_off)) < 0) {		TCPSP_DBG(8, "tcp_state_idx(%d)=%d!!!\n",			  state_off, state_idx);		goto tcp_state_out;	}	new_state = tcpsp_state_table[state_idx].next_state[cp->state];	TCPSP_DBG(18, "new state %s\n", tcpsp_state_name(new_state));  tcp_state_out:	return set_state_timeout(cp, new_state);}/* *	Handle state transitions */int tcpsp_set_state(struct tcpsp_conn *cp,		    int direction, struct iphdr *iph, struct tcphdr *th){	int ret;	spin_lock(&cp->lock);	switch (iph->protocol) {	case IPPROTO_TCP:		ret = set_state(cp, direction*4, th);		break;	default:		ret = -1;	}	spin_unlock(&cp->lock);	return ret;}/* *	tcpsp transmitter */static int tcpsp_xmit(struct sk_buff *skb){

⌨️ 快捷键说明

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