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

📄 tm.c

📁 性能优秀的SIP Proxy
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: tm.c,v 1.34 2006/05/19 14:55:19 bogdan_iancu Exp $ * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of openser, a free SIP server. * * openser 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 * * openser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License  * along with this program; if not, write to the Free Software  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * History: * -------- *  2003-02-18  added t_forward_nonack_{udp, tcp}, t_relay_to_{udp,tcp}, *               t_replicate_{udp, tcp} (andrei) *  2003-02-19  added t_rely_{udp, tcp} (andrei) *  2003-03-06  voicemail changes accepted (jiri) *  2003-03-10  module export interface updated to the new format (andrei) *  2003-03-16  flags export parameter added (janakj) *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei) *  2003-03-30  set_kr for requests only (jiri) *  2003-04-05  s/reply_route/failure_route, onreply_route introduced (jiri) *  2003-04-14  use protocol from uri (jiri) *  2003-07-07  added t_relay_to_tls, t_replicate_tls, t_forward_nonack_tls *              added #ifdef USE_TCP, USE_TLS *              removed t_relay_{udp,tcp,tls} (andrei) *  2003-09-26  added t_forward_nonack_uri() - same as t_forward_nonack() but *              takes no parameters -> forwards to uri (bogdan) *  2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri) *  2004-02-18  t_reply exported via FIFO - imported from VM (bogdan) *  2004-10-01  added a new param.: restart_fr_on_each_reply (andrei) *  2005-05-30  light version of tm_load - find_export dropped -> module  *              interface dosen't need to export internal functions (bogdan) *  2006-01-15  merged functions which diff only via proto (like t_relay, *              t_replicate and t_forward_nonack) (bogdan) */#include <stdio.h>#include <string.h>#include <netdb.h>#include "../../sr_module.h"#include "../../dprint.h"#include "../../error.h"#include "../../ut.h"#include "../../script_cb.h"#include "../../fifo_server.h"#include "../../usr_avp.h"#include "../../mem/mem.h"#include "../../unixsock_server.h"#include "../../items.h"#include "sip_msg.h"#include "h_table.h"#include "ut.h"#include "t_reply.h"#include "uac_fifo.h"#include "uac_unixsock.h"#include "t_fwd.h"#include "t_lookup.h"#include "callid.h"#include "t_cancel.h"#include "t_fifo.h"#include "tm_load.h"MODULE_VERSION/* item functions */static int it_get_tm_branch_idx(struct sip_msg *msg, xl_value_t *res,		xl_param_t *param, int flags);/* fixup functions */static int fixup_t_send_reply(void** param, int param_no);static int fixup_str(void** param, int param_no);static int fixup_str2int( void** param, int param_no);static int fixup_phostport2proxy(void** param, int param_no);static int fixup_str2regexp(void** param, int param_no);static int fixup_local_replied(void** param, int param_no);/* init functions */static int mod_init(void);static int child_init(int rank);/* exported functions */inline static int w_t_check(struct sip_msg* msg, char* , char* );inline static int w_t_release(struct sip_msg* msg, char* , char* );inline static int w_t_retransmit_reply(struct sip_msg* p_msg, char* ,char* );inline static int w_t_newtran(struct sip_msg* p_msg, char* , char* );inline static int w_t_reply(struct sip_msg *msg, char* code, char* text);inline static int w_t_relay(struct sip_msg *p_msg , char *proxy, char* );inline static int w_t_replicate(struct sip_msg *p_msg, char *dst,char* );inline static int w_t_forward_nonack(struct sip_msg* msg, char* proxy, char* );inline static int w_t_on_negative(struct sip_msg* msg, char *go_to, char* );inline static int w_t_on_reply(struct sip_msg* msg, char *go_to, char* );inline static int w_t_on_branch(struct sip_msg* msg, char *go_to, char* );inline static int t_check_status(struct sip_msg* msg, char *regexp, char* );inline static int t_flush_flags(struct sip_msg* msg, char*, char* );inline static int t_local_replied(struct sip_msg* msg, char *type, char* );inline static int t_check_trans(struct sip_msg* msg, char* , char* );inline static int t_was_cancelled(struct sip_msg* msg, char* , char* );/* strings with avp definition */static char *fr_timer_param = FR_TIMER_AVP;static char *fr_inv_timer_param = FR_INV_TIMER_AVP;/* module parameteres */static char *bf_mask_param = NULL;int tm_enable_stats = 1;/* statistic variables */stat_var *tm_rcv_rpls;stat_var *tm_rld_rpls;stat_var *tm_loc_rpls;stat_var *tm_uas_trans;stat_var *tm_uac_trans;stat_var *tm_trans_2xx;stat_var *tm_trans_3xx;stat_var *tm_trans_4xx;stat_var *tm_trans_5xx;stat_var *tm_trans_6xx;stat_var *tm_trans_inuse;static cmd_export_t cmds[]={	{"t_newtran",            w_t_newtran,             0, 0,			REQUEST_ROUTE},	{"t_lookup_request",     w_t_check,               0, 0,			REQUEST_ROUTE},	{"t_reply",              w_t_reply,               2, fixup_t_send_reply,			REQUEST_ROUTE | FAILURE_ROUTE },	{"t_retransmit_reply",   w_t_retransmit_reply,    0, 0,			REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE },	{"t_release",            w_t_release,             0, 0,			REQUEST_ROUTE},	{"t_replicate",          w_t_replicate,           1, fixup_str,			REQUEST_ROUTE},	{"t_relay",              w_t_relay,               0, 0,			REQUEST_ROUTE | FAILURE_ROUTE },	{"t_relay",              w_t_relay,               1,fixup_phostport2proxy,			REQUEST_ROUTE | FAILURE_ROUTE },	{"t_forward_nonack",     w_t_forward_nonack,      0, 0,			REQUEST_ROUTE},	{"t_forward_nonack",     w_t_forward_nonack,      1,fixup_phostport2proxy,			REQUEST_ROUTE},	{"t_on_failure",         w_t_on_negative,         1, fixup_str2int,			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE },	{"t_on_reply",           w_t_on_reply,            1, fixup_str2int,			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE },	{"t_on_branch",          w_t_on_branch,           1, fixup_str2int,			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE },	{"t_check_status",       t_check_status,          1, fixup_str2regexp,			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE },	{"t_write_req",         t_write_req,              2, fixup_t_write,			REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE },	{"t_write_unix",        t_write_unix,             2, fixup_t_write,			REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE },	{"t_flush_flags",       t_flush_flags,            0, 0,			REQUEST_ROUTE | BRANCH_ROUTE  },	{"t_local_replied",     t_local_replied,          1, fixup_local_replied,			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE },	{"t_check_trans",       t_check_trans,            0, 0,			REQUEST_ROUTE | BRANCH_ROUTE },	{"t_was_cancelled",     t_was_cancelled,          0, 0,			FAILURE_ROUTE | ONREPLY_ROUTE },	{"load_tm",             (cmd_function)load_tm,    0, 0,			0},	{0,0,0,0,0}};static param_export_t params[]={	{"ruri_matching",             INT_PARAM,		&ruri_matching},	{"via1_matching",             INT_PARAM,		&via1_matching},	{"fr_timer",                  INT_PARAM,		&(timer_id2timeout[FR_TIMER_LIST])},	{"fr_inv_timer",              INT_PARAM,		&(timer_id2timeout[FR_INV_TIMER_LIST])},	{"wt_timer",                  INT_PARAM,		&(timer_id2timeout[WT_TIMER_LIST])},	{"delete_timer",              INT_PARAM,		&(timer_id2timeout[DELETE_LIST])},	{"retr_timer1p1",             INT_PARAM,		&(timer_id2timeout[RT_T1_TO_1])},	{"retr_timer1p2",             INT_PARAM,		&(timer_id2timeout[RT_T1_TO_2])},	{"retr_timer1p3",             INT_PARAM,		&(timer_id2timeout[RT_T1_TO_3])},	{"retr_timer2",               INT_PARAM,		&(timer_id2timeout[RT_T2])},	{"noisy_ctimer",              INT_PARAM,		&noisy_ctimer},	{"unix_tx_timeout",           INT_PARAM,		&tm_unix_tx_timeout},	{"restart_fr_on_each_reply",  INT_PARAM,		&restart_fr_on_each_reply},	{"fr_timer_avp",              STR_PARAM,		&fr_timer_param},	{"fr_inv_timer_avp",          STR_PARAM,		&fr_inv_timer_param},	{"tw_append",                 STR_PARAM|USE_FUNC_PARAM,		(void*)parse_tw_append },	{"branch_flag_mask",          STR_PARAM,		&bf_mask_param },	{ "enable_stats",             INT_PARAM,		&tm_enable_stats },	{ "pass_provisional_replies", INT_PARAM,		&pass_provisional_replies },	{0,0,0}};stat_export_t mod_stats[] = {	{"received_replies" ,    0,              &tm_rcv_rpls    },	{"relayed_replies" ,     0,              &tm_rld_rpls    },	{"local_replies" ,       0,              &tm_loc_rpls    },	{"UAS_transactions" ,    0,              &tm_uas_trans   },	{"UAC_transactions" ,    0,              &tm_uac_trans   },	{"2xx_transactions" ,    0,              &tm_trans_2xx   },	{"3xx_transactions" ,    0,              &tm_trans_3xx   },	{"4xx_transactions" ,    0,              &tm_trans_4xx   },	{"5xx_transactions" ,    0,              &tm_trans_5xx   },	{"6xx_transactions" ,    0,              &tm_trans_6xx   },	{"inuse_transactions" ,  STAT_NO_RESET,  &tm_trans_inuse },	{0,0,0}};#ifdef STATIC_TMstruct module_exports tm_exports = {#elsestruct module_exports exports= {#endif	"tm",      /* module name*/	cmds,      /* exported functions */	params,    /* exported variables */	mod_stats, /* exported statistics */	mod_init,  /* module initialization function */	(response_function) reply_received,	(destroy_function) tm_shutdown,	child_init /* per-child init function */};/**************************** fixup functions ******************************/static int fixup_str(void** param, int param_no){	str *s;	if (param_no == 1) {		s = (str*)pkg_malloc( sizeof(str) );		if (s==0) {			LOG(L_ERR,"ERROR:tm:fixup_str: no more pkg mem\n");			return E_OUT_OF_MEM;		}		s->s = (char*)*param;		s->len = strlen(s->s);		*param = (void*)s;	}	return 0;}static int fixup_str2int( void** param, int param_no){	unsigned long go_to;	int err;	if (param_no==1) {		go_to=str2s(*param, strlen(*param), &err );		if (err==0) {			pkg_free(*param);			*param=(void *)go_to;			return 0;		} else {			LOG(L_ERR, "ERROR:tm:fixup_str2int: bad number <%s>\n",				(char *)(*param));			return E_CFG;		}	}	return 0;}static int fixup_phostport2proxy(void** param, int param_no){	struct proxy_l *proxy;	char *s;	int port;	int proto;	str host;	if (param_no!=1) {		LOG(L_CRIT,"BUG:tm:fixup_phostport2proxy: called with more than "			" one parameter\n");		return E_BUG;	}	s = (char *) (*param);	if (s==0 || *s==0) {		LOG(L_CRIT,"ERROR:tm:fixup_phostport2proxy: empty parameter\n");		return E_UNSPEC;	}	if (parse_phostport( s, strlen(s), &host.s, &host.len, &port, &proto)!=0){		LOG(L_CRIT,"ERROR:tm:fixup_phostport2proxy: invalid parameter "			"<%s>\n",s);		return E_UNSPEC;	}	proxy = mk_proxy( &host, port, proto, 0);	if (proxy==0) {		LOG(L_ERR, "ERROR:tm:fixup_phostport2proxy: failed to resolve "			"<%.*s>\n", host.len, host.s );		return ser_error;	}	*(param)=proxy;	return 0;}/* (char *code, char *reason_phrase)==>(int code, r_p as is) */static int fixup_t_send_reply(void** param, int param_no){	unsigned long code;	int err;	if (param_no==1){		code=str2s(*param, strlen(*param), &err);		if (err==0){			pkg_free(*param);			*param=(void*)code;			return 0;		}else{			LOG(L_ERR, "TM module:fixup_t_send_reply: bad  number <%s>\n",					(char*)(*param));			return E_UNSPEC;		}	}	/* second param => no conversion*/	return 0;}static int fixup_str2regexp(void** param, int param_no){	regex_t* re;	if (param_no==1) {		if ((re=pkg_malloc(sizeof(regex_t)))==0)			return E_OUT_OF_MEM;		if (regcomp(re, *param, REG_EXTENDED|REG_ICASE|REG_NEWLINE) ) {			pkg_free(re);			LOG(L_ERR,"ERROR: %s : bad re %s\n", exports.name, (char*)*param);			return E_BAD_RE;		}		/* free string */		pkg_free(*param);		/* replace it with the compiled re */		*param=re;	} else {		LOG(L_ERR,"ERROR: fixup_str2regexp called with parameter != 1\n");		return E_BUG;	}	return 0;}static int fixup_local_replied(void** param, int param_no){	char *val;	int n = 0;	if (param_no==1) {		val = (char*)*param;		if (strcasecmp(val,"all")==0) {			n = 1;		} else if (strcasecmp(val,"last")==0) {			n = 0;		} else {			LOG(L_ERR,"ERROR:tm:fixup_local_replied: invalid param \"%s\"\n",				val);			return E_UNSPEC;		}		/* free string */		pkg_free(*param);		/* replace it with the compiled re */		*param=(void*)(long)n;	} else {		LOG(L_ERR,"ERROR:fixup_local_replied: called with parameter != 1\n");		return E_BUG;	}	return 0;}/***************************** init functions *****************************/int load_tm( struct tm_binds *tmb){	tmb->register_tmcb = register_tmcb;	/* replicate function */	tmb->t_replicate = w_t_replicate;	/* relay/forward functions */	tmb->t_relay = w_t_relay;	tmb->t_forward_nonack = (tfwd_f)w_t_forward_nonack;	/* reply functions */	tmb->t_reply = (treply_f)w_t_reply;	tmb->t_reply_with_body = t_reply_with_body;	/* transaction location/status functions */	tmb->t_newtran = t_newtran;	tmb->t_is_local = t_is_local;	tmb->t_get_trans_ident = t_get_trans_ident;	tmb->t_lookup_ident = t_lookup_ident;	tmb->t_gett = get_t;	tmb->t_get_picked = t_get_picked_branch;	/* tm uac functions */	tmb->t_addblind = add_blind_uac;	tmb->t_request_within = req_within;	tmb->t_request_outside = req_outside;	tmb->t_request = request;	tmb->new_dlg_uac = new_dlg_uac;	tmb->dlg_response_uac = dlg_response_uac;	tmb->new_dlg_uas = new_dlg_uas;	tmb->dlg_request_uas = dlg_request_uas;	tmb->free_dlg = free_dlg;	tmb->print_dlg = print_dlg;	return 1;}static int w_t_unref( struct sip_msg *foo, void *bar){	return t_unref(foo);}static int script_init( struct sip_msg *foo, void *bar){	/* we primarily reset all private memory here to make sure	 * private values left over from previous message will	 * not be used again */	/* make sure the new message will not inherit previous	 * message's t_on_negative value	 */	t_on_negative( 0 );	t_on_reply(0);	t_on_branch(0);	set_t(T_UNDEFINED);	/* reset the kr status */	set_kr(0);	return 1;}static int init_gf_mask( char* bf_mask ){	long long int l;	char *end;	if (bf_mask==0)		return 0;	errno = 0;	/* try bases 2, 10 and 16 */	if (bf_mask[0]=='b' || bf_mask[0]=='B') {		l = strtoll( bf_mask+1, &end, 2);		if (*end==0 && errno==0)			goto ok;	}	if (bf_mask[0]=='0' && bf_mask[1]=='x') {		l = strtoll( bf_mask+2, &end, 16);		if (*end==0 && errno==0)			goto ok;

⌨️ 快捷键说明

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