- cancel relayed from failure route deadlock fix ported from stable
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Fri, 15 Sep 2006 16:04:51 +0000 (16:04 +0000)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Fri, 15 Sep 2006 16:04:51 +0000 (16:04 +0000)
(e2e_cancel uses now t_reply_unsafe when called from the failure_route)

Makefile.defs
modules/tm/t_funcs.c
modules/tm/t_fwd.c
modules/tm/tm_load.h

index a09a709..a97fbe8 100644 (file)
@@ -66,7 +66,7 @@ MAIN_NAME=ser
 VERSION = 0
 PATCHLEVEL = 10
 SUBLEVEL =   99
-EXTRAVERSION = -dev43-dns_cache
+EXTRAVERSION = -dev44-dns_cache
 
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
                        $(SUBLEVEL) )
index 94ed9a3..e115dba 100644 (file)
@@ -169,6 +169,8 @@ void put_on_wait(  struct cell  *Trans  )
 
 
 
+/* WARNING: doesn't work from failure route (deadlock, uses t_reply =>
+ *  tries to get the reply lock again) */
 static int kill_transaction( struct cell *trans )
 {
        char err_buffer[128];
@@ -196,6 +198,8 @@ static int kill_transaction( struct cell *trans )
 
 
 
+/* WARNING: doesn't work from failure route (deadlock, uses t_reply => tries
+ *  to get the reply lock again */
 int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
                                int replicate)
 {
index 0806e3e..1920902 100644 (file)
@@ -54,6 +54,8 @@
  *              t_forward_non_ack won't start retransmission on send errors
  *               anymore (WARNING: callers should release/kill the transaction
  *               if error is returned) (andrei)
+ *  2006-09-15  e2e_cancel uses t_reply_unsafe when called from the 
+ *               failure_route and replying to a cancel (andrei)
  */
 
 #include "defs.h"
@@ -517,19 +519,40 @@ void e2e_cancel( struct sip_msg *cancel_msg,
        */
        if (lowest_error<0) {
                LOG(L_ERR, "ERROR: cancel error\n");
-               t_reply( t_cancel, cancel_msg, 500, "cancel error");
-       /* if there are pending branches, let upstream know we
-          are working on it
-       */
+               /* if called from failure_route, make sure that the unsafe version
+                * is called (we are already hold the reply mutex for the cancel
+                * transaction).
+                */
+               if ((rmode==MODE_ONFAILURE) && (t_cancel==get_t()))
+                       t_reply_unsafe( t_cancel, cancel_msg, 500, "cancel error");
+               else
+                       t_reply( t_cancel, cancel_msg, 500, "cancel error");
        } else if (cancel_bm) {
+               /* if there are pending branches, let upstream know we
+                  are working on it
+               */
                DBG("DEBUG: e2e_cancel: e2e cancel proceeding\n");
-               t_reply( t_cancel, cancel_msg, 200, CANCELING );
-       /* if the transaction exists, but there is no more pending
-          branch, tell upstream we're done
-       */
+               /* if called from failure_route, make sure that the unsafe version
+                * is called (we are already hold the reply mutex for the cancel
+                * transaction).
+                */
+               if ((rmode==MODE_ONFAILURE) && (t_cancel==get_t()))
+                       t_reply_unsafe( t_cancel, cancel_msg, 200, CANCELING );
+               else
+                       t_reply( t_cancel, cancel_msg, 200, CANCELING );
        } else {
+               /* if the transaction exists, but there is no more pending
+                  branch, tell upstream we're done
+               */
                DBG("DEBUG: e2e_cancel: e2e cancel -- no more pending branches\n");
-               t_reply( t_cancel, cancel_msg, 200, CANCEL_DONE );
+               /* if called from failure_route, make sure that the unsafe version
+                * is called (we are already hold the reply mutex for the cancel
+                * transaction).
+                */
+               if ((rmode==MODE_ONFAILURE) && (t_cancel==get_t()))
+                       t_reply_unsafe( t_cancel, cancel_msg, 200, CANCEL_DONE );
+               else
+                       t_reply( t_cancel, cancel_msg, 200, CANCEL_DONE );
        }
 }
 
@@ -798,6 +821,10 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
        return 1;
 }
 
+
+
+/* WARNING: doesn't work from failure route (deadlock, uses t_relay_to which
+ *  is failure route unsafe) */
 int t_replicate(struct sip_msg *p_msg,  struct proxy_l *proxy, int proto )
 {
        /* this is a quite horrible hack -- we just take the message
index 2179882..5870f4f 100644 (file)
@@ -76,9 +76,9 @@
 
 struct tm_binds {
        register_tmcb_f  register_tmcb;
-       cmd_function     t_relay_to_udp;
-       cmd_function     t_relay_to_tcp;
-       cmd_function     t_relay;
+       cmd_function     t_relay_to_udp; /* WARNING: failure_route unsafe */
+       cmd_function     t_relay_to_tcp; /* WARNING: failure_route unsafe */ 
+       cmd_function     t_relay;        /* WARNING: failure_route unsafe */
        tnewtran_f       t_newtran;
        treply_f         t_reply;
        treply_wb_f      t_reply_with_body;