Module: sip-router Branch: master Commit: 4f03bb4d8f3d274f2a1f123dc527d2b702b6ad7c URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=4f03bb4d...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Tue Sep 22 16:27:16 2009 +0200
tm: disable 6xx or failover on a per message basis
Added support for disabling 6xx special handling and dns failover on a per transaction basis:
- t_set_disable_6xx(0|1): disable(1)/enable(0) 6xx rfc special handling. - t_set_disable_failover(0|1): disable/enable dns failover.
They both work either on the current transaction (if it was already created) or on the next transaction that will be created (e.g. t_set_disable_6xx(1); t_relay() works).
---
modules/tm/h_table.h | 3 ++ modules/tm/t_funcs.c | 3 +- modules/tm/t_funcs.h | 3 +- modules/tm/t_fwd.c | 5 ++- modules/tm/t_lookup.c | 17 ++++++---- modules/tm/t_reply.c | 8 ++-- modules/tm/tm.c | 83 +++++++++++++++++++++++++++++++++++------------- 7 files changed, 84 insertions(+), 38 deletions(-)
diff --git a/modules/tm/h_table.h b/modules/tm/h_table.h index 463507a..90abd64 100644 --- a/modules/tm/h_table.h +++ b/modules/tm/h_table.h @@ -273,6 +273,9 @@ struct totag_elem { /* don't generate automatically an ACK for local transaction */ # define T_NO_AUTO_ACK (1<<7) #endif + +#define T_DISABLE_6xx (1<<8) /* treat 6xx as a normal reply */ +#define T_DISABLE_FAILOVER (1<<9) /* don't perform dns failover */ #define T_DONT_FORK (T_CANCELED|T_6xx)
/* unsigned short should be enough for a retr. timer: max. 65535 ticks => diff --git a/modules/tm/t_funcs.c b/modules/tm/t_funcs.c index 33d141d..51407f7 100644 --- a/modules/tm/t_funcs.c +++ b/modules/tm/t_funcs.c @@ -90,7 +90,8 @@ static int contacts_avp_index = 0;
int tm_error = 0; /* delayed tm error */
-struct msgid_var user_auto_inv_100; +struct msgid_var user_cell_set_flags; /* extra cell->flags to be set */ +struct msgid_var user_cell_reset_flags; /* extra cell->flags to be reset */
/* ----------------------------------------------------- */ int send_pr_buffer( struct retr_buf *rb, void *buf, int len diff --git a/modules/tm/t_funcs.h b/modules/tm/t_funcs.h index 53d9da1..04ca2d7 100644 --- a/modules/tm/t_funcs.h +++ b/modules/tm/t_funcs.h @@ -74,7 +74,8 @@ struct entry; struct cell;
extern int tm_error; /* delayed tm error */ -extern struct msgid_var user_auto_inv_100; +extern struct msgid_var user_cell_set_flags; +extern struct msgid_var user_cell_reset_flags;
extern int fr_inv_timer_avp_type; extern int_str fr_inv_timer_avp; diff --git a/modules/tm/t_fwd.c b/modules/tm/t_fwd.c index 2ef3025..bde61ce 100644 --- a/modules/tm/t_fwd.c +++ b/modules/tm/t_fwd.c @@ -649,8 +649,9 @@ int add_uac_dns_fallback(struct cell *t, struct sip_msg* msg, int ret; ret=-1; - if (cfg_get(core, core_cfg, use_dns_failover) && - !((t->flags & T_DONT_FORK) || uac_dont_fork(old_uac)) && + if (cfg_get(core, core_cfg, use_dns_failover) && + !((t->flags & (T_DONT_FORK|T_DISABLE_FAILOVER)) || + uac_dont_fork(old_uac)) && dns_srv_handle_next(&old_uac->dns_h, 0)){ if (lock_replies){ /* use reply lock to guarantee nobody is adding a branch diff --git a/modules/tm/t_lookup.c b/modules/tm/t_lookup.c index 1fe5755..58e6fbc 100644 --- a/modules/tm/t_lookup.c +++ b/modules/tm/t_lookup.c @@ -1243,7 +1243,6 @@ static inline void init_new_t(struct cell *new_cell, struct sip_msg *p_msg) struct sip_msg *shm_msg; unsigned int timeout; /* avp timeout gets stored here (in s) */ ticks_t lifetime; - int v;
shm_msg=new_cell->uas.request; new_cell->from.s=shm_msg->from->name.s; @@ -1259,13 +1258,17 @@ static inline void init_new_t(struct cell *new_cell, struct sip_msg *p_msg)
new_cell->method=new_cell->uas.request->first_line.u.request.method; if (p_msg->REQ_METHOD==METHOD_INVITE){ - new_cell->flags |= T_IS_INVITE_FLAG; - if (unlikely(v=get_msgid_val(user_auto_inv_100, p_msg->id, int))) - /* 1 = set, -1 = reset */ - new_cell->flags|=T_AUTO_INV_100 & (!(v+1)-1); - else - new_cell->flags|=T_AUTO_INV_100 & + /* set flags */ + new_cell->flags |= T_IS_INVITE_FLAG | + get_msgid_val(user_cell_set_flags, p_msg->id, int); + new_cell->flags|=T_AUTO_INV_100 & (!cfg_get(tm, tm_cfg, tm_auto_inv_100) -1); + new_cell->flags|=T_DISABLE_6xx & + (!cfg_get(tm, tm_cfg, disable_6xx) -1); + /* reset flags */ + new_cell->flags &= + (~ get_msgid_val(user_cell_reset_flags, p_msg->id, int)); + lifetime=(ticks_t)get_msgid_val(user_inv_max_lifetime, p_msg->id, int); if (likely(lifetime==0)) diff --git a/modules/tm/t_reply.c b/modules/tm/t_reply.c index 6458d2e..28e635e 100644 --- a/modules/tm/t_reply.c +++ b/modules/tm/t_reply.c @@ -1086,10 +1086,10 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code, if (picked_branch==-2) { /* branches open yet */ *should_store=1; *should_relay=-1; - if (new_code>=600 && new_code<=699 && - !cfg_get(tm, tm_cfg, disable_6xx)){ - if (!(Trans->flags & T_6xx)){ - /* cancel only the first time we get a 6xx */ + if (new_code>=600 && new_code<=699){ + if (!(Trans->flags & (T_6xx | T_DISABLE_6xx))){ + /* cancel only the first time we get a 6xx and only + if the 6xx handling is not disabled */ prepare_to_cancel(Trans, cancel_bitmap, 0); Trans->flags|=T_6xx; } diff --git a/modules/tm/tm.c b/modules/tm/tm.c index 64d32fd..22d7da1 100644 --- a/modules/tm/tm.c +++ b/modules/tm/tm.c @@ -228,6 +228,8 @@ static int w_t_reset_retr(struct sip_msg* msg, char* foo, char* bar); static int w_t_set_max_lifetime(struct sip_msg* msg, char* inv, char* noninv); static int w_t_reset_max_lifetime(struct sip_msg* msg, char* foo, char* bar); static int t_set_auto_inv_100(struct sip_msg* msg, char* on_off, char* foo); +static int t_set_disable_6xx(struct sip_msg* msg, char* on_off, char* foo); +static int t_set_disable_failover(struct sip_msg* msg, char* on_off, char* f); static int t_branch_timeout(struct sip_msg* msg, char*, char*); static int t_branch_replied(struct sip_msg* msg, char*, char*); static int t_any_timeout(struct sip_msg* msg, char*, char*); @@ -361,6 +363,10 @@ static cmd_export_t cmds[]={ REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_set_auto_inv_100", t_set_auto_inv_100, 1, fixup_var_int_1, REQUEST_ROUTE}, + {"t_set_disable_6xx", t_set_disable_6xx, 1, fixup_var_int_1, + REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + {"t_set_disable_failover", t_set_disable_failover, 1, fixup_var_int_1, + REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_branch_timeout", t_branch_timeout, 0, 0, FAILURE_ROUTE}, {"t_branch_replied", t_branch_replied, 0, 0, FAILURE_ROUTE}, {"t_any_timeout", t_any_timeout, 0, 0, @@ -1525,31 +1531,62 @@ int w_t_reset_max_lifetime(struct sip_msg* msg, char* foo, char* bar) return t_reset_max_lifetime(); }
+ + +/* helper macro, builds a function for setting a cell flag from the script. + e.g. T_SET_FLAG_GEN_FUNC(t_set_foo, T_FOO) => + static int t_set_foo(struct sip_msg* msg, char*, char* ) + that will expect fparam as first param and will set or reset T_FOO + in the current or next to be created transaction. */ +#define T_SET_FLAG_GEN_FUNC(fname, T_FLAG_NAME) \ +static int fname(struct sip_msg* msg, char* p1, char* p2) \ +{ \ + int state; \ + struct cell* t; \ + unsigned int set_flags; \ + unsigned int reset_flags; \ + \ + if (get_int_fparam(&state, msg, (fparam_t*)p1) < 0) return -1; \ + t=get_t(); \ + /* in REPLY_ROUTE and FAILURE_ROUTE T will be set to current transaction; \ + * in REQUEST_ROUTE T will be set only if the transaction was already \ + * created; if not -> use the static variables */ \ + if (!t || t==T_UNDEFINED ){ \ + set_flags=get_msgid_val(user_cell_set_flags, msg->id, int); \ + reset_flags=get_msgid_val(user_cell_reset_flags, msg->id, int); \ + if (state){ \ + /* set */ \ + set_flags|= T_FLAG_NAME; \ + reset_flags&=~T_FLAG_NAME; \ + }else{ \ + /* reset */ \ + set_flags&=~T_FLAG_NAME; \ + reset_flags|=T_FLAG_NAME; \ + } \ + set_msgid_val(user_cell_set_flags, msg->id, int, set_flags); \ + set_msgid_val(user_cell_reset_flags, msg->id, int, reset_flags); \ + }else{ \ + if (state) \ + t->flags|=T_FLAG_NAME; \ + else \ + t->flags&=~T_FLAG_NAME; \ + } \ + return 1; \ +} + + + /* set automatically sending 100 replies on/off for the current or * next to be created transaction */ -static int t_set_auto_inv_100(struct sip_msg* msg, char* p1, char* p2) -{ - int state; - struct cell* t; - - if (get_int_fparam(&state, msg, (fparam_t*)p1) < 0) return -1; - t=get_t(); - /* in REPLY_ROUTE and FAILURE_ROUTE T will be set to current transaction; - * in REQUEST_ROUTE T will be set only if the transaction was already - * created; if not -> use the static variables */ - if (!t || t==T_UNDEFINED ){ - if (state) - set_msgid_val(user_auto_inv_100, msg->id, int, 1); /* set */ - else - set_msgid_val(user_auto_inv_100, msg->id, int, -1); /* reset */ - }else{ - if (state) - t->flags|=T_AUTO_INV_100; - else - t->flags&=~T_AUTO_INV_100; - } - return 1; -} +T_SET_FLAG_GEN_FUNC(t_set_auto_inv_100, T_AUTO_INV_100) + + +/* set 6xx handling for the current or next to be created transaction */ +T_SET_FLAG_GEN_FUNC(t_set_disable_6xx, T_DISABLE_6xx) + + +/* disable dns failover for the current transaction */ +T_SET_FLAG_GEN_FUNC(t_set_disable_failover, T_DISABLE_FAILOVER)