Module: sip-router
Branch: master
Commit: 4f03bb4d8f3d274f2a1f123dc527d2b702b6ad7c
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=4f03bb4d8f3d274f2a1f123dc527d2b702b6ad7c

Author: Andrei Pelinescu-Onciul <[email protected]>
Committer: Andrei Pelinescu-Onciul <[email protected]>
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)
 
 
 


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to