瀏覽代碼

tm module parameters are changed to use the configuration framework,
that means the parameters are changeable on-the-fly.
("fr_timer_avp", "fr_inv_timer_avp", and "tw_append" are left untouched)

Miklos Tirpak 17 年之前
父節點
當前提交
2b36d88927

+ 170 - 0
modules/tm/config.c

@@ -0,0 +1,170 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2008 iptelorg GmbH
+ *
+ * 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:
+ *    [email protected]
+ *
+ * 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
+ * -------
+ *  2008-02-05	adapting tm module for the configuration framework (Miklos)
+ */
+
+#include "../../cfg/cfg.h"
+#include "../../parser/msg_parser.h" /* method types */
+#include "timer.h"
+#include "t_fwd.h"
+#include "config.h"
+
+struct cfg_group_tm	default_tm_cfg = {
+	/* should be request-uri matching used as a part of pre-3261
+	 * transaction matching, as the standard wants us to do so
+	 * (and is reasonable to do so, to be able to distinguish
+	 * spirals)? turn only off for better interaction with
+	 * devices that are broken and send different r-uri in
+	 * CANCEL/ACK than in original INVITE
+	 */
+	1,	/* ruri_matching */
+	1,	/* via1_matching */
+	FR_TIME_OUT,	/* fr_timeout */
+	INV_FR_TIME_OUT,	/* fr_inv_timeout */
+	WT_TIME_OUT,	/* wait_timeout */
+	DEL_TIME_OUT,	/* delete_timeout */
+	RETR_T1,	/* rt_t1_timeout */
+	RETR_T2,	/* rt_t2_timeout */
+
+	/* maximum time an invite or noninv transaction will live, from
+	 * the moment of creation (overrides larger fr/fr_inv timeouts,
+	 * extensions due to dns failover, fr_inv restart a.s.o)
+	 * Note: after this time the transaction will not be deleted
+	 *  immediately, but forced to go in the wait state or in wait for ack state
+	 *  and then wait state, so it will still be alive for either wait_timeout in
+	 *  the non-inv or "silent" inv. case and for fr_timeout + wait_timeout for an
+	 *  invite transaction (for which  we must wait for the neg. reply ack)
+	 */
+	MAX_INV_LIFETIME,	/* tm_max_inv_lifetime */
+	MAX_NONINV_LIFETIME,	/* tm_max_noninv_lifetime */
+	1,	/* noisy_ctimer */
+	1,	/* tm_auto_inv_100 */
+	500,	/* tm_unix_tx_timeout -- 500 ms by default */
+	1,	/* restart_fr_on_each_reply */
+	0,	/* pass_provisional_replies */
+	1,	/* tm_aggregate_auth */
+	UM_CANCEL_STATEFULL,	/* unmatched_cancel */
+	500,	/* default_code */
+	"Server Internal Error",	/* default_reason */
+	1,	/* reparse_invite */
+	STR_NULL,	/* ac_extra_hdrs */
+
+	0,	/* tm_blst_503 -- if 1 blacklist 503 sources, using tm_blst_503_min,
+		 * tm_blst_503_max, tm_blst_503_default and the Retry-After header
+		 * in the 503 reply */
+	0,	/* tm_blst_503_default -- rfc conformant: do not blacklist if
+		 * no retry-after header is present */
+	0,	/* tm_blst_503 -- minimum 503 blacklist time is 0 sec */
+	3600,	/* tm_blst_503_max -- maximum 503 blacklist time is 3600 sec */
+	METHOD_INVITE,	/* tm_blst_methods_add -- backlist only INVITE
+			 * timeouts by default */
+	~METHOD_BYE,	/* tm_blst_methods_lookup -- look-up the blacklist
+			 * for every method except BYE by default */
+};
+
+void	*tm_cfg = &default_tm_cfg;
+
+cfg_def_t	tm_cfg_def[] = {
+	{"ruri_matching",	CFG_VAR_INT,	0, 1, 0, 0,
+		"perform Request URI check in tranaction matching"},
+	{"via1_matching",	CFG_VAR_INT,	0, 1, 0, 0,
+		"perform first Via header check in tranaction matching"},
+	{"fr_timer",		CFG_VAR_INT,	0, 0, timer_fixup, 0,
+		"timer which hits if no final reply for a request "
+		"or ACK for a negative INVITE reply arrives "
+		"(in milliseconds)"},
+	{"fr_inv_timer",	CFG_VAR_INT,	0, 0, timer_fixup, 0,
+		"timer which hits if no final reply for an INVITE arrives "
+		"after a provisional message was received (in milliseconds)"},
+	{"wt_timer",		CFG_VAR_INT,	0, 0, timer_fixup, 0,
+		"time for which a transaction stays in memory to absorb "
+		"delayed messages after it completed"},
+	{"delete_timer",	CFG_VAR_INT,	0, 0, timer_fixup, 0,
+		"time after which a to-be-deleted transaction currently "
+		"ref-ed by a process will be tried to be deleted again."},
+	{"retr_timer1",		CFG_VAR_INT,	0, 0, timer_fixup, 0,
+		"initial retransmission period (in milliseconds)"},
+	{"retr_timer2",		CFG_VAR_INT,	0, 0, timer_fixup, 0,
+		"maximum retransmission period (in milliseconds)"},
+	{"max_inv_lifetime",	CFG_VAR_INT,	0, 0, timer_fixup, 0,
+		"maximum time an invite transaction can live "
+		"from the moment of creation"},
+	{"max_noninv_lifetime",	CFG_VAR_INT,	0, 0, timer_fixup, 0,
+		"maximum time a non-invite transaction can live "
+		"from the moment of creation"},
+	{"noisy_ctimer",	CFG_VAR_INT,	0, 1, 0, 0,
+		"if set, INVITE transactions that time-out (FR INV timer) "
+		"will be always replied"},
+	{"auto_inv_100",	CFG_VAR_INT,	0, 1, 0, 0,
+		"automatically send 100 to an INVITE"},
+	{"unix_tx_timeout",	CFG_VAR_INT,	0, 0, 0, 0,
+		"Unix socket transmission timeout, in milliseconds"},
+	{"restart_fr_on_each_reply",	CFG_VAR_INT,	0, 1, 0, 0,
+		"restart final response timer on each provisional reply"},
+	{"pass_provisional_replies",	CFG_VAR_INT,	0, 1, 0, 0,
+		"enable/disable passing of provisional replies "
+		"to FIFO applications"},
+	{"aggregate_challenges",	CFG_VAR_INT,	0, 1, 0, 0,
+		"if the final response is a 401 or a 407, aggregate all the "
+		"authorization headers (challenges) "
+		"(rfc3261 requires this to be on)"},
+	{"unmatched_cancel",	CFG_VAR_INT,	0, 2, 0, 0,
+		"determines how CANCELs with no matching transaction are handled "
+		"(0: statefull forwarding, 1: stateless forwarding, 2: drop)"},
+	{"default_code",	CFG_VAR_INT,	400, 699, 0, 0,
+		"default SIP response code sent by t_reply(), if the function "
+		"cannot retrieve its parameters"},
+	{"default_reason",	CFG_VAR_STRING,	0, 0, 0, 0,
+		"default SIP reason phrase sent by t_reply(), if the function "
+		"cannot retrieve its parameters"},
+	{"reparse_invite",	CFG_VAR_INT,	0, 1, 0, 0,
+		"if set to 1, the CANCEL and negative ACK requests are "
+		"constructed from the INVITE message which was sent out "
+		"instead of building them from the received request"},
+	{"ac_extra_hdrs",	CFG_VAR_STR,	0, 0, 0, 0,
+		"header fields prefixed by this parameter value are included "
+		"in the CANCEL and negative ACK messages if they were present "
+		"in the outgoing INVITE (depends on reparse_invite)"},
+	{"blst_503",		CFG_VAR_INT,	0, 1, 0, 0,
+		"if set to 1, blacklist 503 SIP response sources"},
+	{"blst_503_def_timeout",	CFG_VAR_INT,	0, 0, 0, 0,
+		"default 503 blacklist time (in s), when no Retry-After "
+		"header is present"},
+	{"blst_503_min_timeout",	CFG_VAR_INT,	0, 0, 0, 0,
+		"minimum 503 blacklist time (in s)"},
+	{"blst_503_max_timeout",	CFG_VAR_INT,	0, 0, 0, 0,
+		"maximum 503 blacklist time (in s)"},
+	{"blst_methods_add",	CFG_VAR_INT,	0, 0, 0, 0,
+		"bitmap of method types that trigger blacklisting on "
+		"transaction timeouts"},
+	{"blst_methods_lookup",	CFG_VAR_INT,	0, 0, 0, 0,
+		"Bitmap of method types that are looked-up in the blacklist "
+		"before statefull forwarding"},
+	{0, 0, 0, 0, 0, 0}
+};

+ 37 - 0
modules/tm/config.h

@@ -41,6 +41,9 @@
 */
 #include "../../hash_func.h"
 
+#include "../../cfg/cfg.h"
+#include "../../str.h"
+
 /* maximum length of localy generated acknowledgment */
 #define MAX_ACK_LEN   1024
 
@@ -95,4 +98,38 @@
 /* FIFO substitution character */
 #define SUBST_CHAR '!'
 
+struct cfg_group_tm {
+	int	ruri_matching;
+	int	via1_matching;
+	unsigned int	fr_timeout;
+	unsigned int	fr_inv_timeout;
+	unsigned int	wait_timeout;
+	unsigned int	delete_timeout;
+	unsigned int	rt_t1_timeout;
+	unsigned int	rt_t2_timeout;
+	unsigned int	tm_max_inv_lifetime;
+	unsigned int	tm_max_noninv_lifetime;
+	int	noisy_ctimer;
+	int	tm_auto_inv_100;
+	int	tm_unix_tx_timeout;
+	int	restart_fr_on_each_reply;
+	int	pass_provisional_replies;
+	int	tm_aggregate_auth;
+	int	unmatched_cancel;
+	int	default_code;
+	char	*default_reason;
+	int	reparse_invite;
+	str	ac_extra_hdrs;
+	int	tm_blst_503;
+	int	tm_blst_503_default;
+	int	tm_blst_503_min;
+	int	tm_blst_503_max;
+	unsigned int	tm_blst_methods_add;
+	unsigned int	tm_blst_methods_lookup;
+};
+
+extern struct cfg_group_tm	default_tm_cfg;
+extern void	*tm_cfg;
+extern cfg_def_t	tm_cfg_def[];
+
 #endif

+ 2 - 2
modules/tm/t_cancel.c

@@ -43,7 +43,7 @@
 #include <stdio.h> /* for FILE* in fifo_uac_cancel */
 
 #include "defs.h"
-
+#include "config.h"
 
 #include "t_funcs.h"
 #include "../../dprint.h"
@@ -199,7 +199,7 @@ int cancel_branch( struct cell *t, int branch, int flags )
 		}
 	}
 
-	if (reparse_invite) {
+	if (cfg_get(tm, tm_cfg, reparse_invite)) {
 		/* build the CANCEL from the INVITE which was sent out */
 		cancel = build_local_reparse(t, branch, &len, CANCEL, CANCEL_LEN, &t->to);
 	} else {

+ 3 - 3
modules/tm/t_fifo.c

@@ -57,6 +57,7 @@
 #include "../../parser/parse_hname2.h"
 #include "../../parser/contact/parse_contact.h"
 #include "../../tsend.h"
+#include "config.h"
 #include "t_lookup.h"
 #include "t_fwd.h"
 #include "t_fifo.h"
@@ -82,8 +83,6 @@
 
 
 
-int tm_unix_tx_timeout = 500; /* Default is 500 ms */
-
 #define TWRITE_PARAMS          20
 #define TWRITE_VERSION_S       "0.3"
 #define TWRITE_VERSION_LEN     (sizeof(TWRITE_VERSION_S)-1)
@@ -960,7 +959,8 @@ static int write_to_unixsock(char* sockname, int cnt)
 		return -1;
 	}
 
-	if (tsend_dgram_ev(sock, iov_lines_eol, 2 * cnt, tm_unix_tx_timeout) < 0) {
+	if (tsend_dgram_ev(sock, iov_lines_eol, 2 * cnt,
+			cfg_get(tm, tm_cfg, tm_unix_tx_timeout)) < 0) {
 		LOG(L_ERR, "write_to_unixsock: writev failed: %s\n", strerror(errno));
 		return -1;
 	}

+ 0 - 2
modules/tm/t_fifo.h

@@ -38,8 +38,6 @@
 #include "../../parser/msg_parser.h"
 #include "../../sr_module.h"
 
-extern int tm_unix_tx_timeout;
-
 int fixup_t_write( void** param, int param_no);
 
 int parse_tw_append( modparam_t type, void* val);

+ 1 - 2
modules/tm/t_funcs.c

@@ -86,7 +86,6 @@ static int     fr_inv_timer_index = 0;
 
 int tm_error = 0; /* delayed tm error */
 
-int tm_auto_inv_100=1; /* automatically send 100 to an INVITE, default on*/
 struct msgid_var user_auto_inv_100;
 
 /* ----------------------------------------------------- */
@@ -171,7 +170,7 @@ void put_on_wait(  struct cell  *Trans  )
 		4.									WAIT timer executed,
 											transaction deleted
 	*/
-	if (timer_add(&Trans->wait_timer, wait_timeout)==0){
+	if (timer_add(&Trans->wait_timer, cfg_get(tm, tm_cfg, wait_timeout))==0){
 		/* sucess */
 		t_stats_wait();
 	}else{

+ 0 - 2
modules/tm/t_funcs.h

@@ -74,8 +74,6 @@ struct entry;
 struct cell;
 
 extern int tm_error; /* delayed tm error */
-extern int noisy_ctimer;
-extern int tm_auto_inv_100; /*automatically send 100 to an INVITE, default on*/
 extern struct msgid_var user_auto_inv_100;
 
 /* default names for timer's AVPs  */

+ 4 - 6
modules/tm/t_fwd.c

@@ -112,8 +112,6 @@
 /* cancel hop by hop */
 #define E2E_CANCEL_HOP_BY_HOP
 
-int unmatched_cancel=UM_CANCEL_STATEFULL;
-
 static int goto_on_branch = 0, branch_route = 0;
 
 void t_on_branch( unsigned int go_to )
@@ -465,7 +463,7 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
 	*/
 
 	/* print */
-	if (reparse_invite) {
+	if (cfg_get(tm, tm_cfg, reparse_invite)) {
 		/* buffer is built localy from the INVITE which was sent out */
 		if (cancel_msg->add_rm || cancel_msg->body_lumps) {
 			LOG(L_WARN, "WARNING: e2e_cancel_branch: CANCEL is built locally, "
@@ -694,7 +692,7 @@ int t_send_branch( struct cell *t, int branch, struct sip_msg* p_msg ,
 #ifdef USE_DST_BLACKLIST
 	if (cfg_get(core, core_cfg, use_dst_blacklist)
 		&& p_msg
-		&& (p_msg->REQ_METHOD & tm_blst_methods_lookup)
+		&& (p_msg->REQ_METHOD & cfg_get(tm, tm_cfg, tm_blst_methods_lookup))
 	){
 		if (dst_is_blacklisted(&uac->request.dst, p_msg)){
 			su2ip_addr(&ip, &uac->request.dst.to);
@@ -942,7 +940,7 @@ int t_forward_cancel(struct sip_msg* p_msg , struct proxy_l * proxy, int proto,
 	
 	t=0;
 	/* handle cancels for which no transaction was created yet */
-	if (unmatched_cancel==UM_CANCEL_STATEFULL){
+	if (cfg_get(tm, tm_cfg, unmatched_cancel)==UM_CANCEL_STATEFULL){
 		/* create cancel transaction */
 		new_tran=t_newtran(p_msg);
 		if (new_tran<=0 && new_tran!=E_SCRIPT){
@@ -979,7 +977,7 @@ int t_forward_cancel(struct sip_msg* p_msg , struct proxy_l * proxy, int proto,
 		ret=1;
 		goto end;
 	}else /* no coresponding INVITE transaction */
-	     if (unmatched_cancel==UM_CANCEL_DROP){
+	     if (cfg_get(tm, tm_cfg, unmatched_cancel)==UM_CANCEL_DROP){
 				DBG("t_forward_nonack: non matching cancel dropped\n");
 				ret=1; /* do nothing -> drop */
 				goto end;

+ 0 - 2
modules/tm/t_fwd.h

@@ -44,8 +44,6 @@
 enum unmatched_cancel_t { UM_CANCEL_STATEFULL=0, UM_CANCEL_STATELESS,
 							UM_CANCEL_DROP };
 
-extern int unmatched_cancel;
-
 typedef int (*tfwd_f)(struct sip_msg* p_msg , struct proxy_l * proxy );
 typedef int (*taddblind_f)( /*struct cell *t */ );
 

+ 21 - 30
modules/tm/t_lookup.c

@@ -150,16 +150,6 @@
 
 #define HF_LEN(_hf) ((_hf)->len)
 
-/* should be request-uri matching used as a part of pre-3261 
- * transaction matching, as the standard wants us to do so
- * (and is reasonable to do so, to be able to distinguish
- * spirals)? turn only off for better interaction with 
- * devices that are broken and send different r-uri in
- * CANCEL/ACK than in original INVITE
- */
-int ruri_matching=1;
-int via1_matching=1;
-
 /* presumably matching transaction for an e2e ACK */
 static struct cell *t_ack;
 
@@ -503,8 +493,8 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked,
 				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;
+			if (cfg_get(tm, tm_cfg, ruri_matching) && !EQ_REQ_URI_LEN) continue;
+			if (cfg_get(tm, tm_cfg, via1_matching) && !EQ_VIA_LEN(via1)) continue;
 
 			/* length ok -- move on */
 			if (!EQ_STR(callid)) continue;
@@ -512,8 +502,8 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked,
 				get_cseq(p_msg)->number.len)!=0) 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;
+			if (cfg_get(tm, tm_cfg, ruri_matching) && !EQ_REQ_URI_STR) continue;
+			if (cfg_get(tm, tm_cfg, via1_matching) && !EQ_VIA_STR(via1)) continue;
 			
 			if ((t_msg->REQ_METHOD==METHOD_CANCEL) &&
 				(p_msg->REQ_METHOD!=METHOD_CANCEL)){
@@ -564,10 +554,10 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked,
 			 * 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;
+			if (cfg_get(tm, tm_cfg, ruri_matching) && !EQ_REQ_URI_LEN ) continue;
+			if (cfg_get(tm, tm_cfg, via1_matching) && !EQ_VIA_LEN(via1)) continue;
+			if (cfg_get(tm, tm_cfg, ruri_matching) && !EQ_REQ_URI_STR) continue;
+			if (cfg_get(tm, tm_cfg, via1_matching) && !EQ_VIA_STR(via1)) continue;
 
 			/* wow -- we survived all the check! we matched! */
 			DBG("DEBUG: non-2xx ACK matched\n");
@@ -698,9 +688,9 @@ struct cell* t_lookupOriginalT(  struct sip_msg* p_msg )
 		if (get_to(t_msg)->uri.len!=get_to(p_msg)->uri.len)
 			continue;
 #endif
-		if (ruri_matching && !EQ_REQ_URI_LEN)
+		if (cfg_get(tm, tm_cfg, ruri_matching) && !EQ_REQ_URI_LEN)
 			continue;
-		if (via1_matching && !EQ_VIA_LEN(via1))
+		if (cfg_get(tm, tm_cfg, via1_matching) && !EQ_VIA_LEN(via1))
 			continue;
 
 		/* check the content now */
@@ -719,9 +709,9 @@ struct cell* t_lookupOriginalT(  struct sip_msg* p_msg )
 					get_to(t_msg)->uri.len)!=0)
 			continue;
 #endif
-		if (ruri_matching && !EQ_REQ_URI_STR)
+		if (cfg_get(tm, tm_cfg, ruri_matching) && !EQ_REQ_URI_STR)
 			continue;
-		if (via1_matching && !EQ_VIA_STR(via1))
+		if (cfg_get(tm, tm_cfg, via1_matching) && !EQ_VIA_STR(via1))
 			continue;
 
 		/* found */
@@ -982,7 +972,7 @@ int t_check( struct sip_msg* p_msg , int *param_branch )
 			   and we need all the WWW/Proxy Authenticate headers for
 			   401 & 407 replies
 			*/
-			if (tm_aggregate_auth && 
+			if (cfg_get(tm, tm_cfg, tm_aggregate_auth) && 
 					(p_msg->REPLY_STATUS==401 || p_msg->REPLY_STATUS==407)){
 				if (parse_headers(p_msg, HDR_EOH_F,0)==-1){
 					LOG(L_WARN, "WARNING: the reply cannot be "
@@ -1105,16 +1095,17 @@ static inline void init_new_t(struct cell *new_cell, struct sip_msg *p_msg)
 			/* 1 = set, -1 = reset */
 			new_cell->flags|=T_AUTO_INV_100 & (!(v+1)-1);
 		else
-			new_cell->flags|=T_AUTO_INV_100 & ( !tm_auto_inv_100 -1);
+			new_cell->flags|=T_AUTO_INV_100 &
+					(!cfg_get(tm, tm_cfg, tm_auto_inv_100) -1);
 		lifetime=(ticks_t)get_msgid_val(user_inv_max_lifetime,
 												p_msg->id, int);
 		if (likely(lifetime==0))
-			lifetime=tm_max_inv_lifetime;
+			lifetime=cfg_get(tm, tm_cfg, tm_max_inv_lifetime);
 	}else{
 		lifetime=(ticks_t)get_msgid_val(user_noninv_max_lifetime, 
 											p_msg->id, int);
 		if (likely(lifetime==0))
-			lifetime=tm_max_noninv_lifetime;
+			lifetime=cfg_get(tm, tm_cfg, tm_max_noninv_lifetime);
 	}
 	new_cell->on_negative=get_on_negative();
 	new_cell->on_reply=get_on_reply();
@@ -1128,7 +1119,7 @@ static inline void init_new_t(struct cell *new_cell, struct sip_msg *p_msg)
 			DBG("init_new_t: FR__TIMER = %d s\n", timeout);
 			new_cell->fr_timeout=S_TO_TICKS((ticks_t)timeout);
 		}else{
-			new_cell->fr_timeout=fr_timeout;
+			new_cell->fr_timeout=cfg_get(tm, tm_cfg, fr_timeout);
 		}
 	}
 	if (likely(new_cell->fr_inv_timeout==0)){
@@ -1137,18 +1128,18 @@ static inline void init_new_t(struct cell *new_cell, struct sip_msg *p_msg)
 			new_cell->fr_inv_timeout=S_TO_TICKS((ticks_t)timeout);
 			new_cell->flags |= T_NOISY_CTIMER_FLAG;
 		}else{
-			new_cell->fr_inv_timeout=fr_inv_timeout;
+			new_cell->fr_inv_timeout=cfg_get(tm, tm_cfg, fr_inv_timeout);
 		}
 	}
 #ifdef TM_DIFF_RT_TIMEOUT
 	new_cell->rt_t1_timeout=(ticks_t)get_msgid_val(user_rt_t1_timeout,
 												p_msg->id, int);
 	if (likely(new_cell->rt_t1_timeout==0))
-		new_cell->rt_t1_timeout=rt_t1_timeout;
+		new_cell->rt_t1_timeout=cfg_get(tm, tm_cfg, rt_t1_timeout);
 	new_cell->rt_t2_timeout=(ticks_t)get_msgid_val(user_rt_t2_timeout,
 												p_msg->id, int);
 	if (likely(new_cell->rt_t2_timeout==0))
-		new_cell->rt_t2_timeout=rt_t2_timeout;
+		new_cell->rt_t2_timeout=cfg_get(tm, tm_cfg, rt_t2_timeout);
 #endif
 	new_cell->on_branch=get_on_branch();
 }

+ 0 - 2
modules/tm/t_lookup.h

@@ -48,8 +48,6 @@
 #define T_NULL_CELL       ( (struct cell*) 0 )
 
 extern unsigned int     global_msg_id;
-extern int ruri_matching;
-extern int via1_matching;
 
 
 

+ 6 - 6
modules/tm/t_msgbuilder.c

@@ -88,9 +88,6 @@
 		(_p)+=(_str).len;  \
  	} while(0);
 
-str ac_extra_hdrs = STR_STATIC_INIT("");
-int reparse_invite = 1;
-
 
 /* Build a local request based on a previous request; main
    customers of this function are local ACK and local CANCEL
@@ -355,9 +352,12 @@ char *build_local_reparse(struct cell *Trans,unsigned int branch,
 			default:
 				s = lw_next_line(s, invite_buf_end);
 
-				if (ac_extra_hdrs.len
-				&& (s1 + ac_extra_hdrs.len < invite_buf_end)
-				&& (strncasecmp(s1, ac_extra_hdrs.s, ac_extra_hdrs.len) == 0)) {
+				if (cfg_get(tm, tm_cfg, ac_extra_hdrs).len
+				&& (s1 + cfg_get(tm, tm_cfg, ac_extra_hdrs).len < invite_buf_end)
+				&& (strncasecmp(s1,
+						cfg_get(tm, tm_cfg, ac_extra_hdrs).s,
+						cfg_get(tm, tm_cfg, ac_extra_hdrs).len) == 0)
+				) {
 					append_mem_block(d, s1, s - s1);
 				} /* else skip this line */
 				break;

+ 0 - 3
modules/tm/t_msgbuilder.h

@@ -66,9 +66,6 @@
 		(_d) += (_len);\
 	}while(0);
 
-extern str ac_extra_hdrs;
-extern int reparse_invite;
-
 char *build_local(struct cell *Trans, unsigned int branch,
 	unsigned int *len, char *method, int method_len, str *to);
 

+ 16 - 34
modules/tm/t_reply.c

@@ -116,6 +116,7 @@
 #endif
 
 #include "defs.h"
+#include "config.h"
 #include "h_table.h"
 #include "t_hooks.h"
 #include "t_funcs.h"
@@ -129,31 +130,6 @@
 #include "uac.h"
 
 
-/* restart fr timer on each provisional reply, default yes */
-int restart_fr_on_each_reply=1;
-/* if the final reponse is a 401 or a 407, aggregate all the 
- * authorization headers (challenges) (rfc3261 requires this to be on) */
-int tm_aggregate_auth=1;
-
-/* if 1 blacklist 503 sources, using tm_blst_503_min, tm_blst_503_max,
- * tm_blst_503_default and the Retry-After header in the 503 reply */
-int tm_blst_503=0;
-/* default 503 blacklist time (when no Retry-After header is present */
-#ifndef DEFAULT_BLST_TIMEOUT
-#define DEFAULT_BLST_TIMEOUT 60
-#endif
-int tm_blst_503_default=0; /* rfc conformant: do not blacklist if 
-							  no retry-after */
-/* minimum 503 blacklist time */
-int tm_blst_503_min=0; /* in s */
-/* maximum 503 blacklist time */
-int tm_blst_503_max=3600; /* in s */
-
-/* backlist only INVITE timeouts by default */
-unsigned int tm_blst_methods_add=METHOD_INVITE;
-/* look-up the blacklist for every method except BYE by default */
-unsigned int tm_blst_methods_lookup=~METHOD_BYE;
-
 /* are we processing original or shmemed request ? */
 enum route_mode rmode=MODE_REQUEST;
 
@@ -364,7 +340,7 @@ static char *build_ack(struct sip_msg* rpl,struct cell *trans,int branch,
 	to.s=rpl->to->name.s;
 	to.len=rpl->to->len;
 
-	if (reparse_invite) {
+	if (cfg_get(tm, tm_cfg, reparse_invite)) {
 		/* build the ACK from the INVITE which was sent out */
 		return build_local_reparse( trans, branch, ret_len,
 					ACK, ACK_LEN, &to );
@@ -1386,7 +1362,7 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
 			} else {
 				to_tag=0;
 			}
-			if (tm_aggregate_auth && 
+			if (cfg_get(tm, tm_cfg, tm_aggregate_auth) && 
 						(relayed_code==401 || relayed_code==407) &&
 						(auth_reply_count(t, p_msg)>1)){
 				/* aggregate 401 & 407 www & proxy authenticate headers in
@@ -1422,7 +1398,7 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
 				buf=build_res_buf_from_sip_req(500, error_text(relayed_code),
 									to_tag, t->uas.request, &res_len, &bm);
 				relayed_code=500;
-			}else if (tm_aggregate_auth && 
+			}else if (cfg_get(tm, tm_cfg, tm_aggregate_auth) && 
 						(relayed_code==401 || relayed_code==407) &&
 						(auth_reply_count(t, p_msg)>1)){
 				/* aggregate 401 & 407 www & proxy authenticate headers in
@@ -1597,7 +1573,9 @@ enum rps local_reply( struct cell *t, struct sip_msg *p_msg, int branch,
 	}
 	UNLOCK_REPLIES(t);
  
-        if (local_winner >= 0 && pass_provisional_replies && winning_code < 200) {
+        if (local_winner >= 0
+		&& cfg_get(tm, tm_cfg, pass_provisional_replies)
+		&& winning_code < 200) {
 			if (unlikely(!totag_retr && 
 							has_tran_tmcbs(t, TMCB_LOCAL_RESPONSE_OUT) )) {
                         run_trans_callbacks( TMCB_LOCAL_RESPONSE_OUT, t, 0,
@@ -1810,8 +1788,11 @@ int reply_received( struct sip_msg  *p_msg )
 	}
 #ifdef USE_DST_BLACKLIST
 		/* add temporary to the blacklist the source of a 503 reply */
-		if (tm_blst_503 && cfg_get(core, core_cfg, use_dst_blacklist) && (msg_status==503)){
-			blst_503_timeout=tm_blst_503_default;
+		if (cfg_get(tm, tm_cfg, tm_blst_503)
+			&& cfg_get(core, core_cfg, use_dst_blacklist)
+			&& (msg_status==503)
+		){
+			blst_503_timeout=cfg_get(tm, tm_cfg, tm_blst_503_default);
 			if ((parse_headers(p_msg, HDR_RETRY_AFTER_F, 0)==0) && 
 				(p_msg->parsed_flag & HDR_RETRY_AFTER_F)){
 				for (hf=p_msg->headers; hf; hf=hf->next)
@@ -1819,9 +1800,9 @@ int reply_received( struct sip_msg  *p_msg )
 						/* found */
 						blst_503_timeout=(unsigned)(unsigned long)hf->parsed;
 						blst_503_timeout=MAX_unsigned(blst_503_timeout, 
-															tm_blst_503_min);
+									cfg_get(tm, tm_cfg, tm_blst_503_min));
 						blst_503_timeout=MIN_unsigned(blst_503_timeout,
-															tm_blst_503_max);
+									cfg_get(tm, tm_cfg, tm_blst_503_max));
 						break;
 					}
 			}
@@ -1901,7 +1882,8 @@ int reply_received( struct sip_msg  *p_msg )
 		goto done;
 
 	/* update FR/RETR timers on provisional replies */
-	if (is_invite(t) && msg_status<200 && ( restart_fr_on_each_reply ||
+	if (is_invite(t) && msg_status<200 &&
+		( cfg_get(tm, tm_cfg, restart_fr_on_each_reply) ||
 				( (last_uac_status<msg_status) &&
 					((msg_status>=180) || (last_uac_status==0)) )
 			) ) { /* provisional now */

+ 0 - 10
modules/tm/t_reply.h

@@ -37,16 +37,6 @@
 #include "h_table.h"
 
 
-extern int restart_fr_on_each_reply;
-extern int tm_aggregate_auth; /* aggregate authorization header value */
-
-extern int tm_blst_503;
-extern int tm_blst_503_default;  /* in s */
-extern int tm_blst_503_min;      /* in s */
-extern int tm_blst_503_max;      /* in s */
-extern unsigned int tm_blst_methods_add;
-extern unsigned int tm_blst_methods_lookup;
-
 /* reply processing status */
 enum rps {
 	/* something bad happened */

+ 66 - 51
modules/tm/timer.c

@@ -146,8 +146,6 @@
 
 
 
-int noisy_ctimer=1;
-
 struct msgid_var user_fr_timeout;
 struct msgid_var user_fr_inv_timeout;
 #ifdef TM_DIFF_RT_TIMEOUT
@@ -157,27 +155,6 @@ struct msgid_var user_rt_t2_timeout;
 struct msgid_var user_inv_max_lifetime;
 struct msgid_var user_noninv_max_lifetime;
 
-/* default values of timeouts for all the timer list */
-
-ticks_t fr_timeout		=	FR_TIME_OUT;
-ticks_t fr_inv_timeout	=	INV_FR_TIME_OUT;
-ticks_t wait_timeout	=	WT_TIME_OUT;
-ticks_t delete_timeout	=	DEL_TIME_OUT;
-ticks_t rt_t1_timeout	=	RETR_T1;
-ticks_t rt_t2_timeout	=	RETR_T2;
-
-/* maximum time and invite or noninv transaction will live, from
- * the moment of creation (overrides larger fr/fr_inv timeouts,
- * extensions due to dns failover, fr_inv restart a.s.o)
- * Note: after this time the transaction will not be deleted
- *  immediately, but forced to go in the wait state or in wait for ack state 
- *  and then wait state, so it will still be alive for either wait_timeout in 
- *  the non-inv or "silent" inv. case and for fr_timeout + wait_timeout for an
- *  invite transaction (for which  we must wait for the neg. reply ack)
- */
-ticks_t tm_max_inv_lifetime		=	MAX_INV_LIFETIME;
-ticks_t tm_max_noninv_lifetime	=	MAX_NONINV_LIFETIME;
-
 
 /* internal use, val should be unsigned or positive
  *  <= instead of < to get read of gcc warning when 
@@ -196,33 +173,33 @@ ticks_t tm_max_noninv_lifetime	=	MAX_NONINV_LIFETIME;
 /* fix timer values to ticks */
 int tm_init_timers()
 {
-	fr_timeout=MS_TO_TICKS(fr_timeout); 
-	fr_inv_timeout=MS_TO_TICKS(fr_inv_timeout);
-	wait_timeout=MS_TO_TICKS(wait_timeout);
-	delete_timeout=MS_TO_TICKS(delete_timeout);
-	rt_t1_timeout=MS_TO_TICKS(rt_t1_timeout);
-	rt_t2_timeout=MS_TO_TICKS(rt_t2_timeout);
-	tm_max_inv_lifetime=MS_TO_TICKS(tm_max_inv_lifetime);
-	tm_max_noninv_lifetime=MS_TO_TICKS(tm_max_noninv_lifetime);
+	default_tm_cfg.fr_timeout=MS_TO_TICKS(default_tm_cfg.fr_timeout); 
+	default_tm_cfg.fr_inv_timeout=MS_TO_TICKS(default_tm_cfg.fr_inv_timeout);
+	default_tm_cfg.wait_timeout=MS_TO_TICKS(default_tm_cfg.wait_timeout);
+	default_tm_cfg.delete_timeout=MS_TO_TICKS(default_tm_cfg.delete_timeout);
+	default_tm_cfg.rt_t1_timeout=MS_TO_TICKS(default_tm_cfg.rt_t1_timeout);
+	default_tm_cfg.rt_t2_timeout=MS_TO_TICKS(default_tm_cfg.rt_t2_timeout);
+	default_tm_cfg.tm_max_inv_lifetime=MS_TO_TICKS(default_tm_cfg.tm_max_inv_lifetime);
+	default_tm_cfg.tm_max_noninv_lifetime=MS_TO_TICKS(default_tm_cfg.tm_max_noninv_lifetime);
 	/* fix 0 values to 1 tick (minimum possible wait time ) */
-	if (fr_timeout==0) fr_timeout=1;
-	if (fr_inv_timeout==0) fr_inv_timeout=1;
-	if (wait_timeout==0) wait_timeout=1;
-	if (delete_timeout==0) delete_timeout=1;
-	if (rt_t2_timeout==0) rt_t2_timeout=1;
-	if (rt_t1_timeout==0) rt_t1_timeout=1;
-	if (tm_max_inv_lifetime==0) tm_max_inv_lifetime=1;
-	if (tm_max_noninv_lifetime==0) tm_max_noninv_lifetime=1;
+	if (default_tm_cfg.fr_timeout==0) default_tm_cfg.fr_timeout=1;
+	if (default_tm_cfg.fr_inv_timeout==0) default_tm_cfg.fr_inv_timeout=1;
+	if (default_tm_cfg.wait_timeout==0) default_tm_cfg.wait_timeout=1;
+	if (default_tm_cfg.delete_timeout==0) default_tm_cfg.delete_timeout=1;
+	if (default_tm_cfg.rt_t2_timeout==0) default_tm_cfg.rt_t2_timeout=1;
+	if (default_tm_cfg.rt_t1_timeout==0) default_tm_cfg.rt_t1_timeout=1;
+	if (default_tm_cfg.tm_max_inv_lifetime==0) default_tm_cfg.tm_max_inv_lifetime=1;
+	if (default_tm_cfg.tm_max_noninv_lifetime==0) default_tm_cfg.tm_max_noninv_lifetime=1;
 	
 	/* size fit checks */
-	SIZE_FIT_CHECK(fr_timeout, fr_timeout, "fr_timer");
-	SIZE_FIT_CHECK(fr_inv_timeout, fr_inv_timeout, "fr_inv_timer");
+	SIZE_FIT_CHECK(fr_timeout, default_tm_cfg.fr_timeout, "fr_timer");
+	SIZE_FIT_CHECK(fr_inv_timeout, default_tm_cfg.fr_inv_timeout, "fr_inv_timer");
 #ifdef TM_DIFF_RT_TIMEOUT
-	SIZE_FIT_CHECK(rt_t1_timeout, rt_t1_timeout, "retr_timer1");
-	SIZE_FIT_CHECK(rt_t2_timeout, rt_t2_timeout, "retr_timer2");
+	SIZE_FIT_CHECK(rt_t1_timeout, default_tm_cfg.rt_t1_timeout, "retr_timer1");
+	SIZE_FIT_CHECK(rt_t2_timeout, default_tm_cfg.rt_t2_timeout, "retr_timer2");
 #endif
-	SIZE_FIT_CHECK(end_of_life, tm_max_inv_lifetime, "max_inv_lifetime");
-	SIZE_FIT_CHECK(end_of_life, tm_max_noninv_lifetime, "max_noninv_lifetime");
+	SIZE_FIT_CHECK(end_of_life, default_tm_cfg.tm_max_inv_lifetime, "max_inv_lifetime");
+	SIZE_FIT_CHECK(end_of_life, default_tm_cfg.tm_max_noninv_lifetime, "max_noninv_lifetime");
 	
 	memset(&user_fr_timeout, 0, sizeof(user_fr_timeout));
 	memset(&user_fr_inv_timeout, 0, sizeof(user_fr_inv_timeout));
@@ -235,10 +212,48 @@ int tm_init_timers()
 	
 	DBG("tm: tm_init_timers: fr=%d fr_inv=%d wait=%d delete=%d t1=%d t2=%d"
 			" max_inv_lifetime=%d max_noninv_lifetime=%d\n",
-			fr_timeout, fr_inv_timeout, wait_timeout, delete_timeout,
-			rt_t1_timeout, rt_t2_timeout, tm_max_inv_lifetime,
-			tm_max_noninv_lifetime);
+			default_tm_cfg.fr_timeout, default_tm_cfg.fr_inv_timeout,
+			default_tm_cfg.wait_timeout, default_tm_cfg.delete_timeout,
+			default_tm_cfg.rt_t1_timeout, default_tm_cfg.rt_t2_timeout,
+			default_tm_cfg.tm_max_inv_lifetime, default_tm_cfg.tm_max_noninv_lifetime);
+	return 0;
+error:
+	return -1;
+}
+
+/* internal macro for timer_fixup()
+ * performs size fit check if the timer name matches
+ */
+#define IF_IS_TIMER_NAME(cell_member, cfg_name) \
+	if ((name->len == sizeof(cfg_name)-1) && \
+		(memcmp(name->s, cfg_name, sizeof(cfg_name)-1)==0)) { \
+			SIZE_FIT_CHECK(cell_member, t, cfg_name); \
+	}
+
+/* fixup function for the timer values
+ * (called by the configuration framework)
+ */
+int timer_fixup(void *handle, str *name, void **val)
+{
+	ticks_t	t;
+
+	t = MS_TO_TICKS((unsigned int)(long)(*val));
+	/* fix 0 values to 1 tick (minimum possible wait time ) */
+	if (t == 0) t = 1;
+
+	/* size fix checks */
+	IF_IS_TIMER_NAME(fr_timeout, "fr_timer")
+	else IF_IS_TIMER_NAME(fr_inv_timeout, "fr_inv_timer")
+#ifdef TM_DIFF_RT_TIMEOUT
+	else IF_IS_TIMER_NAME(rt_t1_timeout, "retr_timer1")
+	else IF_IS_TIMER_NAME(rt_t2_timeout, "retr_timer2")
+#endif
+	else IF_IS_TIMER_NAME(end_of_life, "max_inv_lifetime")
+	else IF_IS_TIMER_NAME(end_of_life, "max_noninv_lifetime")
+
+	*val = (void *)(long)t;
 	return 0;
+
 error:
 	return -1;
 }
@@ -264,7 +279,7 @@ inline static ticks_t  delete_cell( struct cell *p_cell, int unlock )
 				p_cell, p_cell->ref_count);
 		/* delay the delete */
 		/* TODO: change refcnts and delete on refcnt==0 */
-		return delete_timeout;
+		return cfg_get(tm, tm_cfg, delete_timeout);
 	} else {
 		if (unlock) UNLOCK_HASH(p_cell->hash_index);
 #ifdef EXTRA_DEBUG
@@ -422,7 +437,7 @@ inline static void final_response_handler(	struct retr_buf* r_buf,
 	   world */
 	silent=
 		/* don't go silent if disallowed globally ... */
-		noisy_ctimer==0
+		cfg_get(tm, tm_cfg, noisy_ctimer)==0
 		/* ... or for this particular transaction */
 		&& has_noisy_ctimer(t) == 0
 		/* not for UACs */
@@ -459,7 +474,7 @@ inline static void final_response_handler(	struct retr_buf* r_buf,
 		if (cfg_get(core, core_cfg, use_dst_blacklist)
         		&& r_buf->my_T
 			&& r_buf->my_T->uas.request
-			&& (r_buf->my_T->uas.request->REQ_METHOD & tm_blst_methods_add)
+			&& (r_buf->my_T->uas.request->REQ_METHOD & cfg_get(tm, tm_cfg, tm_blst_methods_add))
 		)
 			dst_blacklist_add( BLST_ERR_TIMEOUT, &r_buf->dst,
 						r_buf->my_T->uas.request);

+ 7 - 13
modules/tm/timer.h

@@ -48,6 +48,7 @@
 
 #include "../../timer.h"
 #include "h_table.h"
+#include "config.h"
 
 /* try to do fast retransmissions (but fall back to slow timer for FR */
 #define TM_FAST_RETR_TIMER
@@ -57,12 +58,14 @@
 #define RT_T1_TIMEOUT(rb)	((rb)->my_T->rt_t1_timeout)
 #define RT_T2_TIMEOUT(rb)	((rb)->my_T->rt_t2_timeout)
 #else
-#define RT_T1_TIMEOUT(rb)	(rt_t1_timeout)
-#define RT_T2_TIMEOUT(rb)	(rt_t2_timeout)
+#define RT_T1_TIMEOUT(rb)	(cfg_get(tm, tm_cfg, rt_t1_timeout))
+#define RT_T2_TIMEOUT(rb)	(cfg_get(tm, tm_cfg, rt_t2_timeout))
 #endif
 
 #define TM_REQ_TIMEOUT(t) \
-	(is_invite(t)?tm_max_inv_lifetime:tm_max_noninv_lifetime)
+	(is_invite(t)? \
+		cfg_get(tm, tm_cfg, tm_max_inv_lifetime): \
+		cfg_get(tm, tm_cfg, tm_max_noninv_lifetime))
 
 
 extern struct msgid_var user_fr_timeout;
@@ -74,18 +77,9 @@ extern struct msgid_var user_rt_t2_timeout;
 extern struct msgid_var user_inv_max_lifetime;
 extern struct msgid_var user_noninv_max_lifetime;
 
-extern ticks_t fr_timeout;
-extern ticks_t fr_inv_timeout;
-extern ticks_t wait_timeout;
-extern ticks_t delete_timeout;
-extern ticks_t rt_t1_timeout;
-extern ticks_t rt_t2_timeout;
-
-extern ticks_t tm_max_inv_lifetime;
-extern ticks_t tm_max_noninv_lifetime;
-
 
 extern int tm_init_timers();
+int timer_fixup(void *handle, str *name, void **val);
 
 ticks_t wait_handler(ticks_t t, struct timer_ln *tl, void* data);
 ticks_t retr_buf_handler(ticks_t t, struct timer_ln *tl, void* data);

+ 48 - 39
modules/tm/tm.c

@@ -84,6 +84,7 @@
  *              added w_t_relay_cancel() (Miklos)
  *  2007-06-05  added t_set_auto_inv_100() and auto_inv_100 (param);
  *               t_set_max_lifetime(), max_{non}inv_lifetime  (andrei)
+ *  2008-02-05	module config parameters use the configuration framework (Miklos)
  */
 
 
@@ -103,7 +104,9 @@
 #include "../../mem/mem.h"
 #include "../../route_struct.h"
 #include "../../route.h"
+#include "../../cfg/cfg.h"
 
+#include "config.h"
 #include "sip_msg.h"
 #include "h_table.h"
 #include "t_hooks.h"
@@ -208,9 +211,6 @@ static char *fr_inv_timer_param = 0 /*FR_INV_TIMER_AVP*/;
 
 static rpc_export_t tm_rpc[];
 
-static int default_code = 500;
-static str default_reason = STR_STATIC_INIT("Server Internal Error");
-
 static int fixup_t_check_status(void** param, int param_no);
 
 static cmd_export_t cmds[]={
@@ -334,38 +334,37 @@ static cmd_export_t cmds[]={
 
 
 static param_export_t params[]={
-	{"ruri_matching",       PARAM_INT, &ruri_matching                        },
-	{"via1_matching",       PARAM_INT, &via1_matching                        },
-	{"fr_timer",            PARAM_INT, &fr_timeout                           },
-	{"fr_inv_timer",        PARAM_INT, &fr_inv_timeout                       },
-	{"wt_timer",            PARAM_INT, &wait_timeout                         },
-	{"delete_timer",        PARAM_INT, &delete_timeout                       },
-	{"retr_timer1",         PARAM_INT, &rt_t1_timeout                        },
-	{"retr_timer2"  ,       PARAM_INT, &rt_t2_timeout                        },
-	{"max_inv_lifetime",    PARAM_INT, &tm_max_inv_lifetime                  },
-	{"max_noninv_lifetime", PARAM_INT, &tm_max_noninv_lifetime               },
-	{"noisy_ctimer",        PARAM_INT, &noisy_ctimer                         },
-	{"auto_inv_100",        PARAM_INT, &tm_auto_inv_100                      },
-	{"uac_from",            PARAM_STRING, &uac_from                          },
-	{"unix_tx_timeout",     PARAM_INT, &tm_unix_tx_timeout                   },
-	{"restart_fr_on_each_reply", PARAM_INT, &restart_fr_on_each_reply        },
+	{"ruri_matching",       PARAM_INT, &default_tm_cfg.ruri_matching         },
+	{"via1_matching",       PARAM_INT, &default_tm_cfg.via1_matching         },
+	{"fr_timer",            PARAM_INT, &default_tm_cfg.fr_timeout            },
+	{"fr_inv_timer",        PARAM_INT, &default_tm_cfg.fr_inv_timeout        },
+	{"wt_timer",            PARAM_INT, &default_tm_cfg.wait_timeout          },
+	{"delete_timer",        PARAM_INT, &default_tm_cfg.delete_timeout        },
+	{"retr_timer1",         PARAM_INT, &default_tm_cfg.rt_t1_timeout         },
+	{"retr_timer2"  ,       PARAM_INT, &default_tm_cfg.rt_t2_timeout         },
+	{"max_inv_lifetime",    PARAM_INT, &default_tm_cfg.tm_max_inv_lifetime   },
+	{"max_noninv_lifetime", PARAM_INT, &default_tm_cfg.tm_max_noninv_lifetime},
+	{"noisy_ctimer",        PARAM_INT, &default_tm_cfg.noisy_ctimer          },
+	{"auto_inv_100",        PARAM_INT, &default_tm_cfg.tm_auto_inv_100       },
+	{"unix_tx_timeout",     PARAM_INT, &default_tm_cfg.tm_unix_tx_timeout    },
+	{"restart_fr_on_each_reply", PARAM_INT, &default_tm_cfg.restart_fr_on_each_reply},
 	{"fr_timer_avp",        PARAM_STRING, &fr_timer_param                    },
 	{"fr_inv_timer_avp",    PARAM_STRING, &fr_inv_timer_param                },
 	{"tw_append",           PARAM_STRING|PARAM_USE_FUNC, 
 													(void*)parse_tw_append   },
-	{"pass_provisional_replies", PARAM_INT, &pass_provisional_replies        },
-	{"aggregate_challenges", PARAM_INT, &tm_aggregate_auth                   },
-	{"unmatched_cancel",    PARAM_INT, &unmatched_cancel                     },
-	{"default_code",        PARAM_INT, &default_code                         },
-	{"default_reason",      PARAM_STR, &default_reason                       },
-	{"reparse_invite",      PARAM_INT, &reparse_invite                       },
-	{"ac_extra_hdrs",       PARAM_STR, &ac_extra_hdrs                        },
-	{"blst_503",            PARAM_INT, &tm_blst_503                          },
-	{"blst_503_def_timeout",PARAM_INT, &tm_blst_503_default                  },
-	{"blst_503_min_timeout",PARAM_INT, &tm_blst_503_min                      },
-	{"blst_503_max_timeout",PARAM_INT, &tm_blst_503_max                      },
-	{"blst_methods_add",    PARAM_INT, &tm_blst_methods_add                  },
-	{"blst_methods_lookup", PARAM_INT, &tm_blst_methods_lookup               },
+	{"pass_provisional_replies", PARAM_INT, &default_tm_cfg.pass_provisional_replies},
+	{"aggregate_challenges", PARAM_INT, &default_tm_cfg.tm_aggregate_auth    },
+	{"unmatched_cancel",    PARAM_INT, &default_tm_cfg.unmatched_cancel      },
+	{"default_code",        PARAM_INT, &default_tm_cfg.default_code          },
+	{"default_reason",      PARAM_STRING, &default_tm_cfg.default_reason     },
+	{"reparse_invite",      PARAM_INT, &default_tm_cfg.reparse_invite        },
+	{"ac_extra_hdrs",       PARAM_STR, &default_tm_cfg.ac_extra_hdrs         },
+	{"blst_503",            PARAM_INT, &default_tm_cfg.tm_blst_503           },
+	{"blst_503_def_timeout",PARAM_INT, &default_tm_cfg.tm_blst_503_default   },
+	{"blst_503_min_timeout",PARAM_INT, &default_tm_cfg.tm_blst_503_min       },
+	{"blst_503_max_timeout",PARAM_INT, &default_tm_cfg.tm_blst_503_max       },
+	{"blst_methods_add",    PARAM_INT, &default_tm_cfg.tm_blst_methods_add   },
+	{"blst_methods_lookup", PARAM_INT, &default_tm_cfg.tm_blst_methods_lookup},
 	{0,0,0}
 };
 
@@ -554,6 +553,7 @@ static int mod_init(void)
 {
 	DBG( "TM - (sizeof 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
 	   maximum number of  branches */
 	if (MAX_BRANCHES+1>31) {
@@ -580,12 +580,21 @@ static int mod_init(void)
 		LOG(L_ERR, "ERROR: mod_init: select init failed\n");
 		return -1;
 	}
-	
+
+	/* the defult timer values must be fixed-up before
+	 * declaring the configuration (Miklos) */
 	if (tm_init_timers()==-1) {
 		LOG(L_ERR, "ERROR: mod_init: timer init failed\n");
 		return -1;
 	}
 
+	/* declare the configuration */
+	if (cfg_declare("tm", tm_cfg_def, &default_tm_cfg, cfg_size(tm),
+			 &tm_cfg)) {
+		LOG(L_ERR, "ERROR: mod_init: failed to declare the configuration\n");
+		return -1;
+	}
+
 	     /* First tm_stat initialization function only allocates the top level stat
 	      * structure in shared memory, the initialization will complete in child
 	      * init with init_tm_stats_child when the final value of estimated_process_count is
@@ -976,16 +985,16 @@ inline static int w_t_reply(struct sip_msg* msg, char* p1, char* p2)
 	}
 
 	if (get_int_fparam(&code, msg, (fparam_t*)p1) < 0) {
-	    code = default_code;
+	    code = cfg_get(tm, tm_cfg, default_code);
 	}
 	
 	if (get_str_fparam(&reason, msg, (fparam_t*)p2) < 0) {
-	    reason = default_reason;
+		r = cfg_get(tm, tm_cfg, default_reason);
+	} else {
+		r = as_asciiz(&reason);
+		if (r == NULL) r = cfg_get(tm, tm_cfg, default_reason);
 	}
 	
-	r = as_asciiz(&reason);
-	if (r == NULL) r = default_reason.s;
-	
 	/* 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
@@ -1001,7 +1010,7 @@ inline static int w_t_reply(struct sip_msg* msg, char* p1, char* p2)
 		ret = -1;
 	}
 
-	if (r) pkg_free(r);
+	if (r && (r != cfg_get(tm, tm_cfg, default_reason))) pkg_free(r);
 	return ret;
 }
 
@@ -1227,7 +1236,7 @@ inline static int w_t_relay_cancel( struct sip_msg  *p_msg ,
 		return 1;
 
 	/* it makes no sense to use this function without reparse_invite=1 */
-	if (!reparse_invite)
+	if (!cfg_get(tm, tm_cfg, reparse_invite))
 		LOG(L_WARN, "WARNING: t_relay_cancel is probably used with "
 			"wrong configuration, check the readme for details\n");
 

+ 9 - 12
modules/tm/uac.c

@@ -69,6 +69,7 @@
 #include "../../ip_addr.h"
 #include "../../socket_info.h"
 #include "../../compiler_opt.h"
+#include "config.h"
 #include "ut.h"
 #include "h_table.h"
 #include "t_hooks.h"
@@ -87,11 +88,6 @@
 
 static char from_tag[FROM_TAG_LEN + 1];
 
-char* uac_from = "sip:[email protected]"; /* Module parameter */
-
-/* Enable/disable passing of provisional replies to FIFO applications */
-int pass_provisional_replies = 0;
-
 /*
  * Initialize UAC
  */
@@ -259,23 +255,24 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
 	}
 	if (uac_r->method->len==INVITE_LEN && memcmp(uac_r->method->s, INVITE, INVITE_LEN)==0){
 		new_cell->flags |= T_IS_INVITE_FLAG;
-		new_cell->flags|=T_AUTO_INV_100 & (!tm_auto_inv_100 -1);
-		lifetime=tm_max_inv_lifetime;
+		new_cell->flags|=T_AUTO_INV_100 &
+				(!cfg_get(tm, tm_cfg, tm_auto_inv_100) -1);
+		lifetime=cfg_get(tm, tm_cfg, tm_max_inv_lifetime);
 	}else
-		lifetime=tm_max_noninv_lifetime;
+		lifetime=cfg_get(tm, tm_cfg, tm_max_noninv_lifetime);
 	new_cell->flags |= T_IS_LOCAL_FLAG;
 	/* init timers hack, new_cell->fr_timer and new_cell->fr_inv_timer
 	 * must be set, or else the fr will happen immediately
 	 * we can't call init_new_t() because we don't have a sip msg
 	 * => we'll ignore t_set_fr() or avp timer value and will use directly the
 	 * module params fr_inv_timer and fr_timer -- andrei */
-	new_cell->fr_timeout=fr_timeout;
-	new_cell->fr_inv_timeout=fr_inv_timeout;
+	new_cell->fr_timeout=cfg_get(tm, tm_cfg, fr_timeout);
+	new_cell->fr_inv_timeout=cfg_get(tm, tm_cfg, fr_inv_timeout);
 	new_cell->end_of_life=get_ticks_raw()+lifetime;
 #ifdef TM_DIFF_RT_TIMEOUT
 	/* same as above for retransmission intervals */
-	new_cell->rt_t1_timeout=rt_t1_timeout;
-	new_cell->rt_t2_timeout=rt_t2_timeout;
+	new_cell->rt_t1_timeout=cfg_get(tm, tm_cfg, rt_t1_timeout);
+	new_cell->rt_t2_timeout=cfg_get(tm, tm_cfg, rt_t2_timeout);
 #endif
 
 	/* better reset avp list now - anyhow, it's useless from

+ 0 - 3
modules/tm/uac.h

@@ -41,9 +41,6 @@
 
 #define DEFAULT_CSEQ 10 /* Default CSeq number */
 
-extern char *uac_from;  /* UAC From parameter */
-extern int pass_provisional_replies; /* Pass provisional replies to fifo applications */
-
 /* structure for UAC interface
  *
  * You can free the memory allocated