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

📄 sctp_hash.c

📁 No7信令,我需要交换类似的代码, 请店长审核,谢谢了,急着交换,谢谢
💻 C
📖 第 1 页 / 共 2 页
字号:
	int low  = sysctl_local_port_range[0];	int high = sysctl_local_port_range[1];	int rem  = (high - low) + 1;	seldom();	snum = sctp_port_rover;	if ( snum > high || snum < low ) {		rare(); snum = low;	}	/* find a fresh, completely unused port number */	for ( ; rem > 0; snum++, rem-- )	{		if ( snum > high || snum < low ) {			rare(); snum = low;		}		sport = htons(snum);		if ( !(sb = sctp_bhash[sctp_bhashfn(sport)]) )			break;		for ( ; sb; sb = sb->bnext )			if ( sb->sport == sport ) {				seldom(); break;			}		if ( sb )			break;	}	if ( rem <= 0 || sb ) {		rare(); return(0);	}	sctp_port_rover = snum;	usual(sport); return(sport);}/* *  ========================================================================= * *  LOOKUP Functions * *  ========================================================================= * *  A fast caching hashing lookup function for SCTP. * *  IMPLEMENTATION NOTES:- All but a few SCTP messages carry our Verification *  Tag.  If the message requires our Verification Tag and we cannot lookup *  the stream on the Verification Tag we treat the packet similar to an OOTB *  packet.  The only restriction that this approach imposes is in the *  selection of our Verification Tag, which cannot be identical to any other *  Verification Tag which we have chosen so far.  We, therefore, check the *  Verification Tag selected at initialization against the cache for *  uniqueness.  This also allows us to acquire the Verification Tag to *  minimize collisions on the hash table.  This allows us to simplify the *  hashing function because we are guaranteeing equal hash coverage using *  selection. *//* *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *  LOOKUP LISTEN - LISTEN hash (sport) * *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *  Listener stream lookup with wildcards.  This will find any bound listener *  stream from the destination address, destination port and device index. *  This is only for INIT and COOKIE ECHO. */static sctp_t *sctp_lookup_listen(uint16_t dport, uint32_t daddr){	sctp_t *sp, *result = NULL;	int hiscore = 0;	for ( sp = sctp_lhash[sctp_lhashfn(dport)]; sp; sp = sp->next )	{		int score = 0;		if ( sp->sport ) {			if ( sp->sport != dport )				continue;			score++;		}		if ( sp->saddr ) {			if ( !sctp_find_saddr(sp, daddr) )				continue;			score++;		}		if ( score == 2 ) {			result = sp;			break;		}		if ( score > hiscore ) {			hiscore = score;			result = sp;		}	}	usual(result); return result;}/* *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *  LOOKUP - TCB hash (port pair) * *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *  We do the hard match here, because we don't have valid v_tags or p_tags. *  We don't have the information anyways.  We are just looking for an *  established stream which can accept the packet based on port numbers and *  source and destination addresses.  This is used for INIT and exceptional *  COOKIE ECHO cases as well as ICMP lookups for failed sent INIT messages. * */#define sctp_match_tcb(__sp, __saddr, __daddr, __sport, __dport) \	( ((__sport) == (__sp)->sport) && \	  ((__dport) == (__sp)->dport) && \	  (sctp_find_saddr((__sp),(__saddr))) && \	  (sctp_find_daddr((__sp),(__daddr))) )sctp_t *sctp_lookup_tcb(uint16_t sport, uint16_t dport, uint32_t saddr, uint32_t daddr){	sctp_t *sp;	for ( sp = sctp_thash[sctp_thashfn(sport, dport)]; sp; sp = sp->tnext )		if ( sctp_match_tcb(sp, saddr, daddr, sport, dport) )			break;	return sp;}/* *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *  LOOKUP PTAG - Peer hash (peer tag) * *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *  We can either match fast and loose or slow and sure.  We have a peer tag *  which is validation enough without walking the address lists most of the *  time.  The INIT and COOKIE ECHO stuff needs it for checking peer tags and *  peer tie tags.  ICMP needs this for looking up all packets which were *  returned that we sent out with the peer's tag (excepts INIT which has no *  tag, we use TCB ICMP lookup for that).  ICMP lookups match with reversed *  source and destination addresses. */#ifndef SCTP_SLOW_VERIFICATION#define	sctp_match_ptag(__sp, __saddr, __daddr, __p_tag, __sport, __dport) \	( ((__p_tag) == (__sp)->p_tag) && \	  ((__sport) == (__sp)->sport) && \	  ((__dport) == (__sp)->dport) )#else#define	sctp_match_ptag(__sp, __saddr, __daddr, __p_tag, __sport, __dport) \	( ((__p_tag) == (__sp)->p_tag) && \	  ((__sport) == (__sp)->sport) && \	  ((__dport) == (__sp)->dport) && \	  (sctp_find_saddr((__sp),(__saddr))) && \	  (sctp_find_daddr((__sp),(__daddr))) )#endifsctp_t *sctp_lookup_ptag(uint32_t p_tag, uint16_t sport, uint16_t dport, uint32_t saddr, uint16_t daddr){	sctp_t *sp;	(void)saddr;	(void)daddr;	for ( sp = sctp_phash[sctp_phashfn(p_tag)]; sp; sp = sp->pnext )		if ( sctp_match_ptag(sp, saddr, daddr, p_tag, sport, dport) )			break;	return sp;}/* *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *  LOOKUP VTAG - Established hash (local tag) * *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *  This is the main lookup for data transfer on established streams.  This *  should run as fast and furious as possible.  We run fast and loose and *  rely on the verification tag and port numbers only.  We cache and hash *  so a stream of back-to-back packets to the same destination (bursty *  traffic) will whirl.  Because we MD4 hash verification tags when we *  generate them, the hash should get good random distribution with minimum *  collisions. * */#ifndef	SCTP_SLOW_VERIFICATION#define sctp_match_vtag(__sp, __saddr, __daddr, __v_tag, __sport, __dport) \	( ((__v_tag) == (__sp)->v_tag) && \	  ((__sport) == (__sp)->sport) )#else#define sctp_match_vtag(__sp, __saddr, __daddr, __v_tag, __sport, __dport) \	( ((__v_tag) == (__sp)->v_tag) && \	  ((__sport) == (__sp)->sport) && \	  ((__dport) == (__sp)->dport) && \	  (sctp_find_saddr((__sp),(__daddr))) && \	  (sctp_find_daddr((__sp),(__saddr))) )#endifstatic sctp_t *sctp_lookup_vtag(uint32_t v_tag, uint16_t sport, uint16_t dport, uint32_t saddr, uint16_t daddr){	sctp_t *sp;	unsigned int hash = sctp_cachefn(v_tag);	(void)saddr;	(void)daddr;	if ( !(sp = sctp_cache[hash]) ||			!sctp_match_vtag(sp, saddr, daddr, v_tag, sport, dport) )	for ( sp = sctp_vhash[sctp_vhashfn(v_tag)]; sp; sp = sp->next )		if ( sctp_match_vtag(sp, saddr, daddr, v_tag, sport, dport) ) {			sctp_cache[hash] = sp; break; }	return sp;}/* *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *  LOOKUP COOKIE ECHO - Special lookup rules for cookie echo chunks * *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */static sctp_t *sctp_lookup_cookie_echo(ck, v_tag, sport, dport, saddr, daddr)	struct sctp_cookie *ck;	uint32_t v_tag;	uint16_t dport;	uint16_t sport;	uint32_t daddr;	uint32_t saddr;{	sctp_t *sp = NULL;	/* quick sanity checks on cookie */	if ( ck->v_tag == v_tag && ck->sport == sport && ck->dport == dport )	{	if (	/* RFC 2960 5.2.4 (A) */	        ( ck->l_ttag && ck->p_ttag && (sp = sctp_lookup_vtag(ck->l_ttag, sport, dport, saddr, daddr)) )		/* RFC 2960 5.2.4 (B) */	     || ( (sp = sctp_lookup_vtag(v_tag, sport, dport, saddr, daddr)) )		/* RFC 2960 5.2.4 (C) */	     || ( !ck->l_ttag && !ck->p_ttag && (sp = sctp_lookup_ptag(ck->p_tag, sport, dport, saddr, daddr)) )		/* RFC 2960 5.2.4 (D) */	     || ( (sp = sctp_lookup_listen(sport, saddr)) ) )		return(sp);	}	else rare();	seldom();	return(NULL);}/* *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *  LOOKUP - Established hash (local verification tag with fallbacks) * *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *  Stream hash lookup with fast path for data.  This uses verification tag *  when it is available.  Source address and port are checked after the *  verification tag matches.  When called for INIT and COOKIE ECHO messages, *  the function returns a listening (bind) hash lookup.  For SHUTDOWN *  COMPLETE and ABORT messages with the T-bit set, an icmp (peer tag) lookup *  is performed instead. */sctp_t *sctp_lookup(struct sctphdr *sh, uint32_t daddr, uint32_t saddr){	sctp_t *sp = NULL;	struct sctpchdr *ch = (struct sctpchdr *)(sh+1);	int ctype = ch->type & SCTP_CTYPE_MASK;	uint32_t v_tag = sh->v_tag;	uint16_t dport = sh->dest;	uint16_t sport = sh->srce;	if ( v_tag )	{		/* fast path */		if ( ctype == SCTP_CTYPE_SACK || ctype == SCTP_CTYPE_DATA )			return sctp_lookup_vtag(v_tag, dport, sport, daddr, saddr);		switch ( ctype )		{		/* See RFC 2960 Section 8.5.1 */		case SCTP_CTYPE_ABORT:		case SCTP_CTYPE_SHUTDOWN_COMPLETE:			if ( ch->flags & 0x1 ) /* T bit set */				return sctp_lookup_ptag(v_tag, dport, sport, daddr, saddr);		default:			if ( (sp = sctp_lookup_vtag(v_tag, dport, sport, daddr, saddr)) )				return(sp);			if ( ctype == SCTP_CTYPE_ABORT )				/* check abort for conn ind */				if ( (sp = sctp_lookup_listen(dport, daddr)) )					return(sp);		case SCTP_CTYPE_INIT:			break;		case SCTP_CTYPE_COOKIE_ECHO: {			struct sctp_cookie *ck = (struct sctp_cookie *)((struct sctp_cookie_echo *)ch)->cookie;			return sctp_lookup_cookie_echo(ck, v_tag, dport, sport, daddr, saddr);		}		}	}	else if ( ctype == SCTP_CTYPE_INIT )		if ( (sp = sctp_lookup_listen(dport, daddr)) ||		     (sp = sctp_lookup_tcb(dport, sport, daddr, saddr)) )			return(sp);	seldom(); return(NULL);}

⌨️ 快捷键说明

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