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

📄 tm.c

📁 性能优秀的SIP Proxy
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	l = strtoll( bf_mask, &end, 10);	if (*end==0 && errno==0)		goto ok;	return -1;ok:	gflags_mask = ~((unsigned int)l);	DBG("DEBUG:tm:init_gf_mask: gflags_mask is %x\n",gflags_mask);	return 0;}static int mod_init(void){	LOG(L_INFO,"TM - initializing...\n");	/* checking if we have sufficient bitmap capacity for given	   maximum number of  branches */	if (MAX_BRANCHES+1>31) {		LOG(L_CRIT, "Too many max UACs for UAC branch_bm_t bitmap: %d\n",			MAX_BRANCHES );		return -1;	}	/* if statistics are disabled, prevent their registration to core */	if (tm_enable_stats==0)#ifdef STATIC_TM		tm_exports.stats = 0;#else		exports.stats = 0;#endif	if (init_callid() < 0) {		LOG(L_CRIT, "Error while initializing Call-ID generator\n");		return -1;	}	if (register_fifo_cmd(fifo_uac, "t_uac_dlg", 0) < 0) {		LOG(L_CRIT, "cannot register fifo t_uac\n");		return -1;	}	if (register_fifo_cmd(fifo_uac_cancel, "t_uac_cancel", 0) < 0) {		LOG(L_CRIT, "cannot register fifo t_uac_cancel\n");		return -1;	}	if (register_fifo_cmd(fifo_hash, "t_hash", 0)<0) {		LOG(L_CRIT, "cannot register hash\n");		return -1;	}	if (register_fifo_cmd(fifo_t_reply, "t_reply", 0)<0) {		LOG(L_CRIT, "cannot register t_reply\n");		return -1;	}	if (unixsock_register_cmd("t_uac_dlg", unixsock_uac) < 0) {		LOG(L_CRIT, "cannot register t_uac with the unix server\n");		return -1;	}	if (unixsock_register_cmd("t_uac_cancel", unixsock_uac_cancel) < 0) {		LOG(L_CRIT, "cannot register t_uac_cancel with the unix server\n");		return -1;	}	if (unixsock_register_cmd("t_hash", unixsock_hash) < 0) {		LOG(L_CRIT, "cannot register t_hash with the unix server\n");		return -1;	}	if (unixsock_register_cmd("t_reply", unixsock_t_reply) < 0) {		LOG(L_CRIT, "cannot register t_reply with the unix server\n");		return -1;	}	/* building the hash table*/	if (!init_hash_table()) {		LOG(L_ERR, "ERROR: mod_init: initializing hash_table failed\n");		return -1;	}	/* init static hidden values */	init_t();	if (!tm_init_timers()) {		LOG(L_ERR, "ERROR: mod_init: timer init failed\n");		return -1;	}	/* register the timer function */	register_timer( timer_routine , 0 /* empty attr */, 1 );	if (uac_init()==-1) {		LOG(L_ERR, "ERROR: mod_init: uac_init failed\n");		return -1;	}	if (init_tmcb_lists()!=1) {		LOG(L_CRIT, "ERROR:tm:mod_init: failed to init tmcb lists\n");		return -1;	}	tm_init_tags();	init_twrite_lines();	if (init_twrite_sock() < 0) {		LOG(L_ERR, "ERROR:tm:mod_init: Unable to create socket\n");		return -1;	}	/* register post-script clean-up function */	if (register_script_cb( w_t_unref, POST_SCRIPT_CB|REQ_TYPE_CB, 0)<0 ) {		LOG(L_ERR,"ERROR:tm:mod_init: failed to register POST request "			"callback\n");		return -1;	}	if (register_script_cb( script_init, PRE_SCRIPT_CB|REQ_TYPE_CB , 0)<0 ) {		LOG(L_ERR,"ERROR:tm:mod_init: failed to register PRE request "			"callback\n");		return -1;	}	if ( init_avp_params( fr_timer_param, fr_inv_timer_param)<0 ){		LOG(L_ERR,"ERROR:tm:mod_init: failed to process timer AVPs\n");		return -1;	}	if ( init_gf_mask( bf_mask_param )<0 ) {		LOG(L_ERR,"ERROR:tm:mod_init: failed to process "			"\"branch_flag_mask\" param\n");		return -1;	}	if(xl_add_extra("T_branch_idx", it_get_tm_branch_idx, 100, NULL)!=0)	{		LOG(L_ERR,"ERROR:tm:mod_init: failed to register pvar "			"[T_branch_idx]\n");		return -1;	}	return 0;}static int child_init(int rank){	if (child_init_callid(rank) < 0) {		LOG(L_ERR, "ERROR:tm:child_init: Error while initializing "			"Call-ID generator\n");		return -2;	}	return 0;}/**************************** wrapper functions ***************************/static int t_check_status(struct sip_msg* msg, char *regexp, char *foo){	regmatch_t pmatch;	struct cell *t;	char *status;	char backup;	int branch;	int n;	/* first get the transaction */	if (t_check( msg , 0 )==-1) return -1;	if ( (t=get_t())==0) {		LOG(L_ERR, "ERROR: t_check_status: cannot check status for a reply "			"which has no T-state established\n");		return -1;	}	backup = 0;	switch (route_type) {		case REQUEST_ROUTE:			/* use the status of the last sent reply */			status = int2str( t->uas.status, 0);			break;		case ONREPLY_ROUTE:			/* use the status of the current reply */			status = msg->first_line.u.reply.status.s;			backup = status[msg->first_line.u.reply.status.len];			status[msg->first_line.u.reply.status.len] = 0;			break;		case FAILURE_ROUTE:			/* use the status of the winning reply */			if ( (branch=t_get_picked_branch())<0 ) {				LOG(L_CRIT,"BUG:t_check_status: no picked branch (%d) for"					" a final response in MODE_ONFAILURE\n", branch);				return -1;			}			status = int2str( t->uac[branch].last_received , 0);			break;		default:			LOG(L_ERR,"ERROR:t_check_status: unsupported route_type %d\n",					route_type);			return -1;	}	DBG("DEBUG:t_check_status: checked status is <%s>\n",status);	/* do the checking */	n = regexec((regex_t*)regexp, status, 1, &pmatch, 0);	if (backup) status[msg->first_line.u.reply.status.len] = backup;	if (n!=0) return -1;	return 1;}inline static int t_check_trans(struct sip_msg* msg, char *foo, char *bar){	struct cell *trans;	struct cell *bkup;	int ret;	if (msg->REQ_METHOD==METHOD_CANCEL) {		/* parse needed hdrs*/		if (check_transaction_quadruple(msg)==0) {			LOG(L_ERR, "ERROR:tm:t_check_trans: too few headers\n");			return 0; /*drop request!*/		}		if (!msg->hash_index)			msg->hash_index = tm_hash(msg->callid->body,get_cseq(msg)->number);		/* performe lookup */		trans = t_lookupOriginalT(  msg );		if (trans) {			UNREF( trans );			return 1;		} else {			return -1;		}	} else {		bkup = get_t();		ret = t_lookup_request( msg , 0);		if ( (trans=get_t())!=0 ) UNREF(trans);		set_t( bkup );		switch (ret) {			case 1:				/* transaction found */				return 1;			case -2:				/* e2e ACK found */				return 1;			default:				/* notfound */				return -1;		}	}	return ret;}static int t_flush_flags(struct sip_msg* msg, char *foo, char *bar){	struct cell *t;	/* first get the transaction */	t = get_t();	if ( t==0 || t==T_UNDEFINED) {		LOG(L_ERR, "ERROR: t_flush_flags: cannot flush flags for a message "			"which has no T-state established\n");		return -1;	}	/* do the flush */	t->uas.request->flags = msg->flags&gflags_mask;	return 1;}inline static int t_local_replied(struct sip_msg* msg, char *all, char *bar){	struct cell *t;	int all_rpls;	int i;	if (t_check( msg , 0 )!=1) {		LOG(L_ERR, "ERROR:t_local_replied: no transaction was set up\n");		return -1;	}	t = get_t();	all_rpls = (int)(long)all;	/* is last reply local ? */	if (t->relaied_reply_branch!=-2)		return -1;	/* were all replies local or none  */	if (all_rpls) {		for( i=t->first_branch ; i<t->nr_of_outgoings ; i++ ) {			if (t->uac[i].flags&T_UAC_HAS_RECV_REPLY)				return -1;		}	}	return 1;}static int t_was_cancelled(struct sip_msg* msg, char *foo, char *bar){	struct cell *t;	/* first get the transaction */	if (t_check( msg , 0 )==-1) return -1;	if ( (t=get_t())==0) {		LOG(L_ERR, "ERROR:tm:t_was_cancelled: cannot check cancel flag for "			"a reply without a transaction\n");		return -1;	}	return (t->flags&T_WAS_CANCELLED_FLAG)?1:-1;}inline static int w_t_check(struct sip_msg* msg, char* str, char* str2){	return t_check( msg , 0  ) ? 1 : -1;}inline static int w_t_forward_nonack( struct sip_msg* msg, char* proxy,										char* foo){	struct cell *t;	if (t_check( msg , 0 )!=1) {		LOG(L_ERR, "ERROR:tm:w_t_forward_nonack: "				"can't forward when no transaction was set up\n");		return -1;	}	t=get_t();	if (msg->REQ_METHOD==METHOD_ACK) {		LOG(L_WARN,"WARNING:tm:w_t_forward_nonack: you don't really "			"want to fwd hbh ACK\n");		return -1;	}	return t_forward_nonack( t, msg, ( struct proxy_l *)proxy);}inline static int w_t_reply(struct sip_msg* msg, char* str, char* str2){	struct cell *t;	if (msg->REQ_METHOD==METHOD_ACK) {		LOG(L_WARN, "WARNING: t_reply: ACKs are not replied\n");		return -1;	}	if (t_check( msg , 0 )==-1) return -1;	t=get_t();	if (!t) {		LOG(L_ERR, "ERROR: t_reply: cannot send a t_reply to a message "			"for which no T-state has been established\n");		return -1;	}	/* if called from reply_route, make sure that unsafe version	 * is called; we are already in a mutex and another mutex in	 * the safe version would lead to a deadlock	 */	switch (route_type) {		case FAILURE_ROUTE:			DBG("DEBUG: t_reply_unsafe called from w_t_reply\n");			return t_reply_unsafe(t, msg, (unsigned int)(long) str, str2);		case REQUEST_ROUTE:			return t_reply( t, msg, (unsigned int)(long) str, str2);		default:			LOG(L_CRIT, "BUG:tm:w_t_reply: unsupported route_type (%d)\n",				route_type);			return -1;	}}inline static int w_t_release(struct sip_msg* msg, char* str, char* str2){	struct cell *t;	if (t_check( msg  , 0  )==-1) return -1;	t=get_t();	if ( t && t!=T_UNDEFINED ) 		return t_release_transaction( t );	return 1;}inline static int w_t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar){	struct cell *t;	if (t_check( p_msg  , 0 )==-1) 		return 1;	t=get_t();	if (t) {		if (p_msg->REQ_METHOD==METHOD_ACK) {			LOG(L_WARN, "WARNING: : ACKs transmit_replies not replied\n");			return -1;		}		return t_retransmit_reply( t );	} else 		return -1;}inline static int w_t_newtran( struct sip_msg* p_msg, char* foo, char* bar ) {	/* t_newtran returns 0 on error (negative value means	   'transaction exists' */	return t_newtran( p_msg );}inline static int w_t_on_negative( struct sip_msg* msg, char *go_to, char *foo){	t_on_negative( (unsigned int )(long) go_to );	return 1;}inline static int w_t_on_reply( struct sip_msg* msg, char *go_to, char *foo ){	t_on_reply( (unsigned int )(long) go_to );	return 1;}inline static int w_t_on_branch( struct sip_msg* msg, char *go_to, char *foo ){	t_on_branch( (unsigned int )(long) go_to );	return 1;}inline static int w_t_replicate(struct sip_msg *p_msg, char *dst, char *_bar){	return t_replicate( p_msg, (str*)dst );}inline static int w_t_relay( struct sip_msg  *p_msg , char *proxy, char *foo){	struct cell *t;	if (route_type==FAILURE_ROUTE) {		t=get_t();		if (!t || t==T_UNDEFINED) {			LOG(L_CRIT, "BUG:tm:w_t_relay: undefined T\n");			return -1;		}		if (t_forward_nonack( t, p_msg, (struct proxy_l *)proxy)<=0 ) {			LOG(L_ERR, "ERROR:tm:w_t_relay: t_forward_nonack failed\n");			return -1;		}		return 1;	}	if (route_type==REQUEST_ROUTE) {		return t_relay_to( p_msg, (struct proxy_l *)proxy,			0 /* no replication */ );	}	LOG(L_CRIT, "ERROR:tm:w_t_relay: unsupported route type: %d\n",		route_type);	return 0;}/* item functions */static int it_get_tm_branch_idx(struct sip_msg *msg, xl_value_t *res,		xl_param_t *param, int flags){	extern int _tm_branch_index;	int l = 0;	char *ch = NULL;	if(msg==NULL || res==NULL)		return -1;		ch = int2str(_tm_branch_index, &l);	res->rs.s = ch;	res->rs.len = l;	res->ri = _tm_branch_index;	res->flags = XL_VAL_STR|XL_VAL_INT|XL_TYPE_INT;	return 0;}

⌨️ 快捷键说明

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