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

📄 t_lookup.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 3 页
字号:
	{		t_msg = p_cell->uas.request;		if (!t_msg) continue; /* skip UAC transactions */		if (!isACK) {				/* compare lengths first */ 			if (!EQ_LEN(callid)) continue;			if (!EQ_LEN(cseq)) continue;			if (!EQ_LEN(from)) continue;			if (!EQ_LEN(to)) continue;			if (ruri_matching && !EQ_REQ_URI_LEN) continue;			if (via1_matching && !EQ_VIA_LEN(via1)) continue;			/* length ok -- move on */			if (!EQ_STR(callid)) continue;			if (!EQ_STR(cseq)) continue;			if (!EQ_STR(from)) continue;			if (!EQ_STR(to)) continue;			if (ruri_matching && !EQ_REQ_URI_STR) continue;			if (via1_matching && !EQ_VIA_STR(via1)) continue;			/* request matched ! */			DBG("DEBUG: non-ACK matched\n");			goto found;		} else { /* it's an ACK request*/			/* ACK's relate only to INVITEs */			if (t_msg->REQ_METHOD!=METHOD_INVITE) continue;			/* From|To URI , CallID, CSeq # must be always there */			/* compare lengths now */			if (!EQ_LEN(callid)) continue;			/* CSeq only the number without method ! */			if (get_cseq(t_msg)->number.len!=get_cseq(p_msg)->number.len)				continue;			if (! EQ_LEN(from)) continue;			/* To only the uri -- to many UACs screw up tags  */			if (get_to(t_msg)->uri.len!=get_to(p_msg)->uri.len)				continue;			if (!EQ_STR(callid)) continue;			if (memcmp(get_cseq(t_msg)->number.s, get_cseq(p_msg)->number.s,				get_cseq(p_msg)->number.len)!=0) continue;			if (!EQ_STR(from)) continue;			if (memcmp(get_to(t_msg)->uri.s, get_to(p_msg)->uri.s,				get_to(t_msg)->uri.len)!=0) continue;			/* it is e2e ACK/200 */			if (p_cell->uas.status<300 && e2e_ack_trans==0) {				/* all criteria for proxied ACK are ok */				if (p_cell->relaied_reply_branch!=-2) {					e2e_ack_trans=p_cell;					continue;				}				/* it's a local UAS transaction */				if (dlg_matching(p_cell, p_msg))					goto found;				continue;			}			/* it is not an e2e ACK/200 -- perhaps it is 			 * local negative case; in which case we will want			 * more elements to match: r-uri and via; allow			 * mismatching r-uri as an config option for broken			 * UACs */			if (ruri_matching && !EQ_REQ_URI_LEN ) continue;			if (via1_matching && !EQ_VIA_LEN(via1)) continue;			if (ruri_matching && !EQ_REQ_URI_STR) continue;			if (via1_matching && !EQ_VIA_STR(via1)) continue;			/* wow -- we survived all the check! we matched! */			DBG("DEBUG: non-2xx ACK matched\n");			goto found;		} /* ACK */	} /* synonym loop */notfound:	if (e2e_ack_trans) {		p_cell=e2e_ack_trans;		goto e2e_ack;	}			/* no transaction found */	set_t(0);	if (!leave_new_locked) {		UNLOCK_HASH(p_msg->hash_index);	}	DBG("DEBUG: t_lookup_request: no transaction found\n");	return -1;e2e_ack:	t_ack=p_cell;	/* e2e proxied ACK */	set_t(0);	if (!leave_new_locked) {		UNLOCK_HASH(p_msg->hash_index);	}	DBG("DEBUG: t_lookup_request: e2e proxy ACK found\n");	return -2;found:	set_t(p_cell);	REF_UNSAFE( T );	set_kr(REQ_EXIST);	UNLOCK_HASH( p_msg->hash_index );	DBG("DEBUG: t_lookup_request: transaction found (T=%p)\n",T);	return 1;}/* function lookups transaction being canceled by CANCEL in p_msg; * it returns: *       0 - transaction wasn't found *       T - transaction found */struct cell* t_lookupOriginalT(  struct sip_msg* p_msg ){	struct cell     *p_cell;	unsigned int     hash_index;	struct sip_msg  *t_msg;	struct via_param *branch;	int ret;	/* start searching in the table */	hash_index = p_msg->hash_index;	DBG("DEBUG: t_lookupOriginalT: searching on hash entry %d\n",hash_index );	/* first of all, look if there is RFC3261 magic cookie in branch; if	 * so, we can do very quick matching and skip the old-RFC bizzar	 * comparison of many header fields	 */	if (!p_msg->via1) {		LOG(L_ERR, "ERROR: t_lookupOriginalT: no via\n");		set_t(0);		return 0;	}	branch=p_msg->via1->branch;	if (branch && branch->value.s && branch->value.len>MCOOKIE_LEN			&& memcmp(branch->value.s,MCOOKIE,MCOOKIE_LEN)==0) {		/* huhuhu! the cookie is there -- let's proceed fast */		LOCK_HASH(hash_index);		ret=matching_3261(p_msg, &p_cell,				/* we are seeking the original transaction --				 * skip CANCEL transactions during search				 */				METHOD_CANCEL);		if (ret==1) goto found; else goto notfound;	}	/* no cookies --proceed to old-fashioned pre-3261 t-matching */	LOCK_HASH(hash_index);	/* all the transactions from the entry are compared */	for (p_cell=get_tm_table()->entrys[hash_index].first_cell;		p_cell; p_cell = p_cell->next_cell )	{		t_msg = p_cell->uas.request;		if (!t_msg) continue; /* skip UAC transactions */		/* we don't cancel CANCELs ;-) */		if (t_msg->REQ_METHOD==METHOD_CANCEL)			continue;		/* check lengths now */			if (!EQ_LEN(callid))			continue;		if (get_cseq(t_msg)->number.len!=get_cseq(p_msg)->number.len)			continue;		if (!EQ_LEN(from))			continue;#ifdef CANCEL_TAG		if (!EQ_LEN(to))			continue;#else		/* relaxed matching -- we don't care about to-tags anymore,		 * many broken UACs screw them up and ignoring them does not		 * actually hurt		 */		if (get_to(t_msg)->uri.len!=get_to(p_msg)->uri.len)			continue;#endif		if (ruri_matching && !EQ_REQ_URI_LEN)			continue;		if (via1_matching && !EQ_VIA_LEN(via1))			continue;		/* check the content now */		if (!EQ_STR(callid))			continue;		if (memcmp(get_cseq(t_msg)->number.s,			get_cseq(p_msg)->number.s,get_cseq(p_msg)->number.len)!=0)			continue;		if (!EQ_STR(from))			continue;#ifdef CANCEL_TAG		if (!EQ_STR(to))			continue;#else		if (memcmp(get_to(t_msg)->uri.s, get_to(p_msg)->uri.s,					get_to(t_msg)->uri.len)!=0)			continue;#endif		if (ruri_matching && !EQ_REQ_URI_STR)			continue;		if (via1_matching && !EQ_VIA_STR(via1))			continue;		/* found */		goto found;	}notfound:	/* no transaction found */	DBG("DEBUG: t_lookupOriginalT: no CANCEL matching found! \n" );	UNLOCK_HASH(hash_index);	DBG("DEBUG: t_lookupOriginalT completed\n");	return 0;found:	DBG("DEBUG: t_lookupOriginalT: canceled transaction"		" found (%p)! \n",p_cell );	REF_UNSAFE( p_cell );	UNLOCK_HASH(hash_index);	DBG("DEBUG: t_lookupOriginalT completed\n");	return p_cell;}/* Returns 0 - nothing found *         1  - T found */int t_reply_matching( struct sip_msg *p_msg , int *p_branch ){	struct cell*  p_cell;	int hash_index   = 0;	int entry_label  = 0;	int branch_id    = 0;	char  *hashi, *branchi, *p, *n;	int hashl, branchl;	int scan_space;	str cseq_method;	str req_method;	char *loopi;	int loopl;	char *syni;	int synl;		short is_cancel;	/* make compiler warnings happy */	loopi=0;	loopl=0;	syni=0;	synl=0;	/* split the branch into pieces: loop_detection_check(ignored),	 hash_table_id, synonym_id, branch_id */	if (!(p_msg->via1 && p_msg->via1->branch && p_msg->via1->branch->value.s))		goto nomatch2;	/* we do RFC 3261 tid matching and want to see first if there is	 * magic cookie in branch */	if (p_msg->via1->branch->value.len<=MCOOKIE_LEN)		goto nomatch2;	if (memcmp(p_msg->via1->branch->value.s, MCOOKIE, MCOOKIE_LEN)!=0)		goto nomatch2;	p=p_msg->via1->branch->value.s+MCOOKIE_LEN;	scan_space=p_msg->via1->branch->value.len-MCOOKIE_LEN;	/* hash_id */	n=eat_token2_end( p, p+scan_space, BRANCH_SEPARATOR);	hashl=n-p;	scan_space-=hashl;	if (!hashl || scan_space<2 || *n!=BRANCH_SEPARATOR) goto nomatch2;	hashi=p;	p=n+1;scan_space--;	if (!syn_branch) {		/* md5 value */		n=eat_token2_end( p, p+scan_space, BRANCH_SEPARATOR );		loopl = n-p;		scan_space-= loopl;		if (n==p || scan_space<2 || *n!=BRANCH_SEPARATOR) 			goto nomatch2;		loopi=p;		p=n+1; scan_space--;	} else {		/* synonym id */		n=eat_token2_end( p, p+scan_space, BRANCH_SEPARATOR);		synl=n-p;		scan_space-=synl;		if (!synl || scan_space<2 || *n!=BRANCH_SEPARATOR) 			goto nomatch2;		syni=p;		p=n+1;scan_space--;	}	/* branch id  -  should exceed the scan_space */	n=eat_token_end( p, p+scan_space );	branchl=n-p;	if (!branchl ) goto nomatch2;	branchi=p;	/* sanity check */	if ((hash_index=reverse_hex2int(hashi, hashl))<0		||hash_index>=TABLE_ENTRIES		|| (branch_id=reverse_hex2int(branchi, branchl))<0		||branch_id>=MAX_BRANCHES		|| (syn_branch ? (entry_label=reverse_hex2int(syni, synl))<0 			: loopl!=MD5_LEN )	) {		DBG("DEBUG: t_reply_matching: poor reply labels %d label %d "			"branch %d\n",hash_index, entry_label, branch_id );		goto nomatch2;	}	DBG("DEBUG: t_reply_matching: hash %d label %d branch %d\n",		hash_index, entry_label, branch_id );	/* search the hash table list at entry 'hash_index'; lock the	   entry first 	*/	cseq_method=get_cseq(p_msg)->method;	is_cancel=cseq_method.len==CANCEL_LEN 		&& memcmp(cseq_method.s, CANCEL, CANCEL_LEN)==0;	LOCK_HASH(hash_index);	for (p_cell = get_tm_table()->entrys[hash_index].first_cell; p_cell; 		p_cell=p_cell->next_cell) {		/* first look if branch matches */		if (syn_branch) {			if (p_cell->label != entry_label) 				continue;		} else {			if ( memcmp(p_cell->md5, loopi,MD5_LEN)!=0)					continue;		}		/* sanity check ... too high branch ? */		if ( branch_id>=p_cell->nr_of_outgoings )			continue;		/* does method match ? (remember -- CANCELs have the same branch		   as canceled transactions) */		req_method=p_cell->method;		if ( /* method match */			! ((cseq_method.len==req_method.len 			&& memcmp( cseq_method.s, req_method.s, cseq_method.len )==0)			/* or it is a local cancel */			|| (is_cancel && is_invite(p_cell)				/* commented out -- should_cancel_branch set it to				   BUSY_BUFFER to avoid collisions with replies;				   thus, we test here by buffer size				*/				/* && p_cell->uac[branch_id].local_cancel.buffer ))) */				&& p_cell->uac[branch_id].local_cancel.buffer_len ))) 			continue;		/* we passed all disqualifying factors .... the transaction has been		   matched !		*/		set_t(p_cell);		*p_branch = branch_id;		REF_UNSAFE( T );		UNLOCK_HASH(hash_index);		DBG("DEBUG: t_reply_matching: reply matched (T=%p)!\n",T);		/* if this is a 200 for INVITE, we will wish to store to-tags to be		 * able to distinguish retransmissions later and not to call 		 * TMCB_RESPONSE_OUT uselessly; we do it only if callbacks are		 * enabled -- except callback customers, nobody cares about 		 * retransmissions of multiple 200/INV or ACK/200s		 */		if (is_invite(p_cell) && p_msg->REPLY_STATUS>=200 		&& p_msg->REPLY_STATUS<300 		&& ( (!is_local(p_cell) &&				has_tran_tmcbs(p_cell,TMCB_RESPONSE_OUT|TMCB_E2EACK_IN) )			|| (is_local(p_cell)&&has_tran_tmcbs(p_cell,TMCB_LOCAL_COMPLETED))		)) {			if (parse_headers(p_msg, HDR_TO, 0)==-1) {				LOG(L_ERR, "ERROR: t_reply_matching: to parsing failed\n");			}		}		if (!is_local(p_cell)) {			run_trans_callbacks( TMCB_RESPONSE_IN, T, T->uas.request, p_msg,				p_msg->REPLY_STATUS);		}		return 1;	} /* for cycle */	/* nothing found */	UNLOCK_HASH(hash_index);	DBG("DEBUG: t_reply_matching: no matching transaction exists\n");nomatch2:	DBG("DEBUG: t_reply_matching: failure to match a transaction\n");	*p_branch = -1;	set_t(0);	return -1;}/* Determine current transaction * *                   Found      Not Found     Error (e.g. parsing) *  Return Value     1          0             -1 *  T                ptr        0             T_UNDEFINED */int t_check( struct sip_msg* p_msg , int *param_branch ){	int local_branch;	/* is T still up-to-date ? */	DBG("DEBUG: t_check: msg id=%d global id=%d T start=%p\n", 		p_msg->id,global_msg_id,T);	if ( p_msg->id != global_msg_id || T==T_UNDEFINED )	{		global_msg_id = p_msg->id;		T = T_UNDEFINED;		/* transaction lookup */		if ( p_msg->first_line.type==SIP_REQUEST ) {			/* force parsing all the needed headers*/			if (parse_headers(p_msg, HDR_EOH, 0 )==-1) {				LOG(L_ERR, "ERROR: t_check: parsing error\n");				return -1;			}

⌨️ 快捷键说明

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