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

📄 tm.c

📁 SIP Express Router, Linux下的SIP代理服务器,小巧实用,开发测试VoIP设备和应用的必备.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: tm.c,v 1.118.2.1 2005/02/16 23:24:14 bogdan Exp $ * * TM module * * * *************************************************** * * Jiri's Source Memorial                          * * *                                                 * * * Welcome, pilgrim ! This is the greatest place   * * * where dramatic changes happend. There are not   * * * many places with a history like this, as there  * * * are not so many people like Jiri, one of the    * * * ser's fathers, who brought everywhere the wind  * * * of change, the flood of clean-up. We all felt   * * * his fatherly eye watching over us day and night.* * *                                                 * * * Please, preserve this codework heritage, as     * * * it's unlikely for fresh, juicy pieces of code to  * * * arise to give him the again the chance to       * * * demonstrate his clean-up and improvement skills.* * *                                                 * * * Hereby, we solicit you to adopt this historical * * * piece of code. For $100, your name will be      * * * be printed in this banner and we will use       * * * collected funds to create and display an ASCII  * * * statue of Jiri  .                               * * *************************************************** * * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of ser, a free SIP server. * * ser 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 * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: *    info@iptel.org * * ser 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) */#include "defs.h"#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 "sip_msg.h"#include "h_table.h"#include "t_hooks.h"#include "tm_load.h"#include "ut.h"#include "t_reply.h"#include "uac.h"#include "uac_fifo.h"#include "uac_unixsock.h"#include "t_fwd.h"#include "t_lookup.h"#include "t_stats.h"#include "callid.h"#include "t_cancel.h"#include "t_fifo.h"MODULE_VERSION/* fixup functions */static int fixup_t_send_reply(void** param, int param_no);static int fixup_str2int( void** param, int param_no);static int fixup_hostport2proxy(void** param, int param_no);static int fixup_str2regexp(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* str, char* str2);inline static int w_t_reply(struct sip_msg* msg, char* str, char* str2);inline static int w_t_release(struct sip_msg* msg, char* str, char* str2);inline static int w_t_retransmit_reply(struct sip_msg* p_msg, char* foo,				char* bar );inline static int w_t_newtran(struct sip_msg* p_msg, char* foo, char* bar );inline static int w_t_relay( struct sip_msg  *p_msg , char *_foo, char *_bar);inline static int w_t_relay_to_udp( struct sip_msg  *p_msg , char *proxy, 				 char *);#ifdef USE_TCPinline static int w_t_relay_to_tcp( struct sip_msg  *p_msg , char *proxy,				char *);#endif#ifdef USE_TLSinline static int w_t_relay_to_tls( struct sip_msg  *p_msg , char *proxy,				char *);#endifinline static int w_t_replicate( struct sip_msg  *p_msg , 				char *proxy, /* struct proxy_l *proxy expected */				char *_foo       /* nothing expected */ );inline static int w_t_replicate_udp( struct sip_msg  *p_msg , 				char *proxy, /* struct proxy_l *proxy expected */				char *_foo       /* nothing expected */ );#ifdef USE_TCPinline static int w_t_replicate_tcp( struct sip_msg  *p_msg , 				char *proxy, /* struct proxy_l *proxy expected */				char *_foo       /* nothing expected */ );#endif#ifdef USE_TLSinline static int w_t_replicate_tls( struct sip_msg  *p_msg , 				char *proxy, /* struct proxy_l *proxy expected */				char *_foo       /* nothing expected */ );#endifinline static int w_t_forward_nonack(struct sip_msg* msg, char* str, char* );inline static int w_t_forward_nonack_uri(struct sip_msg* msg, char* str,char*);inline static int w_t_forward_nonack_udp(struct sip_msg* msg, char* str,char*);#ifdef USE_TCPinline static int w_t_forward_nonack_tcp(struct sip_msg* msg, char* str,char*);#endif#ifdef USE_TLSinline static int w_t_forward_nonack_tls(struct sip_msg* msg, char* str,char*);#endifinline static int w_t_on_negative(struct sip_msg* msg, char *go_to, char *foo);inline static int w_t_on_reply(struct sip_msg* msg, char *go_to, char *foo );inline static int t_check_status(struct sip_msg* msg, char *regexp, char *foo);static char *fr_timer_param = FR_TIMER_AVP;static char *fr_inv_timer_param = FR_INV_TIMER_AVP;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},	{"t_release",          w_t_release,             0, 0,			REQUEST_ROUTE},	{T_RELAY_TO_UDP,       w_t_relay_to_udp,        2, fixup_hostport2proxy,			REQUEST_ROUTE|FAILURE_ROUTE},#ifdef USE_TCP	{T_RELAY_TO_TCP,       w_t_relay_to_tcp,        2, fixup_hostport2proxy,			REQUEST_ROUTE|FAILURE_ROUTE},#endif#ifdef USE_TLS	{T_RELAY_TO_TLS,       w_t_relay_to_tls,        2, fixup_hostport2proxy,			REQUEST_ROUTE|FAILURE_ROUTE},#endif	{"t_replicate",        w_t_replicate,           2, fixup_hostport2proxy,			REQUEST_ROUTE},	{"t_replicate_udp",    w_t_replicate_udp,       2, fixup_hostport2proxy,			REQUEST_ROUTE},#ifdef USE_TCP	{"t_replicate_tcp",    w_t_replicate_tcp,       2, fixup_hostport2proxy,			REQUEST_ROUTE},#endif#ifdef USE_TLS	{"t_replicate_tls",    w_t_replicate_tls,       2, fixup_hostport2proxy,			REQUEST_ROUTE},#endif	{T_RELAY,              w_t_relay,               0, 0,			REQUEST_ROUTE | FAILURE_ROUTE },	{T_FORWARD_NONACK,     w_t_forward_nonack,      2, fixup_hostport2proxy,			REQUEST_ROUTE},	{T_FORWARD_NONACK_URI, w_t_forward_nonack_uri,  0, 0,			REQUEST_ROUTE},	{T_FORWARD_NONACK_UDP, w_t_forward_nonack_udp,  2, fixup_hostport2proxy,			REQUEST_ROUTE},#ifdef USE_TCP	{T_FORWARD_NONACK_TCP, w_t_forward_nonack_tcp,  2, fixup_hostport2proxy,			REQUEST_ROUTE},#endif#ifdef USE_TLS	{T_FORWARD_NONACK_TLS, w_t_forward_nonack_tls,  2, fixup_hostport2proxy,			REQUEST_ROUTE},#endif	{"t_on_failure",       w_t_on_negative,         1, fixup_str2int,			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE },	{"t_on_reply",         w_t_on_reply,            1, fixup_str2int,			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE },	{"t_check_status",     t_check_status,          1, fixup_str2regexp,			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE },	{"t_write_req",       t_write_req,              2, fixup_t_write,			REQUEST_ROUTE | FAILURE_ROUTE },	{"t_write_unix",      t_write_unix,             2, fixup_t_write,	                REQUEST_ROUTE | FAILURE_ROUTE },	/* not applicable from the script */	{"register_tmcb",      (cmd_function)register_tmcb,     NO_SCRIPT,   0, 0},	{"load_tm",            (cmd_function)load_tm,           NO_SCRIPT,   0, 0},	{T_REPLY_WB,           (cmd_function)t_reply_with_body, NO_SCRIPT,   0, 0},	{T_IS_LOCAL,           (cmd_function)t_is_local,        NO_SCRIPT,   0, 0},	{T_GET_TI,             (cmd_function)t_get_trans_ident, NO_SCRIPT,   0, 0},	{T_LOOKUP_IDENT,       (cmd_function)t_lookup_ident,    NO_SCRIPT,   0, 0},	{T_ADDBLIND,           (cmd_function)add_blind_uac,     NO_SCRIPT,   0, 0},	{"t_request_within",   (cmd_function)req_within,        NO_SCRIPT,   0, 0},	{"t_request_outside",  (cmd_function)req_outside,       NO_SCRIPT,   0, 0},	{"t_request",          (cmd_function)request,           NO_SCRIPT,   0, 0},	{"new_dlg_uac",        (cmd_function)new_dlg_uac,       NO_SCRIPT,   0, 0},	{"dlg_response_uac",   (cmd_function)dlg_response_uac,  NO_SCRIPT,   0, 0},	{"new_dlg_uas",        (cmd_function)new_dlg_uas,       NO_SCRIPT,   0, 0},	{"dlg_request_uas",    (cmd_function)dlg_request_uas,   NO_SCRIPT,   0, 0},	{"free_dlg",           (cmd_function)free_dlg,          NO_SCRIPT,   0, 0},	{"print_dlg",          (cmd_function)print_dlg,         NO_SCRIPT,   0, 0},	{T_GETT,               (cmd_function)get_t,             NO_SCRIPT,   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                         },	{"uac_from",            STR_PARAM, &uac_from                             },	{"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 },	{0,0,0}};#ifdef STATIC_TMstruct module_exports tm_exports = {#elsestruct module_exports exports= {#endif	"tm",	/* -------- exported functions ----------- */	cmds,	/* ------------ exported variables ---------- */	params,		mod_init, /* module initialization function */	(response_function) reply_received,	(destroy_function) tm_shutdown,	0, /* w_onbreak, */	child_init /* per-child init function */};/**************************** fixup functions ******************************/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: fixup_str2int: bad number <%s>\n",				(char *)(*param));			return E_CFG;		}	}	return 0;}/* (char *hostname, char *port_nr) ==> (struct proxy_l *, -)  */static int fixup_hostport2proxy(void** param, int param_no){	unsigned int port;	char *host;	int err;	struct proxy_l *proxy;	str s;		DBG("TM module: fixup_hostport2proxy(%s, %d)\n", (char*)*param, param_no);	if (param_no==1){		DBG("TM module: fixup_hostport2proxy: param 1.. do nothing, wait for #2\n");		return 0;	} else if (param_no==2) {		host=(char *) (*(param-1)); 		port=str2s(*param, strlen(*param), &err);		if (err!=0) {			LOG(L_ERR, "TM module:fixup_hostport2proxy: bad port number <%s>\n",				(char*)(*param));			 return E_UNSPEC;		}		s.s = host;		s.len = strlen(host);		proxy=mk_proxy(&s, port, 0); /* FIXME: udp or tcp? */		if (proxy==0) {			LOG(L_ERR, "ERROR: fixup_hostport2proxy: bad host name in URI <%s>\n",				host );			return E_BAD_ADDRESS;		}		/* success -- fix the first parameter to proxy now ! */		/* FIXME: janakj, mk_proxy doesn't make copy of host !! */		/*pkg_free( *(param-1)); you're right --andrei*/		*(param-1)=proxy;		return 0;	} else {		LOG(L_ERR,"ERROR: fixup_hostport2proxy called with parameter #<>{1,2}\n");		return E_BUG;	}}/* (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;}/***************************** init functions *****************************/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 */	if (foo->first_line.type==SIP_REQUEST){		/* make sure the new message will not inherit previous			message's t_on_negative value		*/		t_on_negative( 0 );		t_on_reply(0);		/* reset the kr status */		set_kr(0);		/* set request mode so that multiple-mode actions know		 * how to behave */		rmode=MODE_REQUEST;	}	return 1;}static int mod_init(void){	DBG( "TM - (size of cell=%ld, sip_msg=%ld) initializing...\n", 			(long)sizeof(struct cell), (long)sizeof(struct sip_msg));	/* checking if we have sufficient bitmap capacity for given

⌨️ 快捷键说明

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