Browse code

- cancel relayed from failure route deadlock fix ported from stable (e2e_cancel uses now t_reply_unsafe when called from the failure_route)

Andrei Pelinescu-Onciul authored on 15/09/2006 16:04:51
Showing 4 changed files
... ...
@@ -66,7 +66,7 @@ MAIN_NAME=ser
66 66
 VERSION = 0
67 67
 PATCHLEVEL = 10
68 68
 SUBLEVEL =   99
69
-EXTRAVERSION = -dev43-dns_cache
69
+EXTRAVERSION = -dev44-dns_cache
70 70
 
71 71
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
72 72
 			$(SUBLEVEL) )
... ...
@@ -169,6 +169,8 @@ void put_on_wait(  struct cell  *Trans  )
169 169
 
170 170
 
171 171
 
172
+/* WARNING: doesn't work from failure route (deadlock, uses t_reply =>
173
+ *  tries to get the reply lock again) */
172 174
 static int kill_transaction( struct cell *trans )
173 175
 {
174 176
 	char err_buffer[128];
... ...
@@ -196,6 +198,8 @@ static int kill_transaction( struct cell *trans )
196 196
 
197 197
 
198 198
 
199
+/* WARNING: doesn't work from failure route (deadlock, uses t_reply => tries
200
+ *  to get the reply lock again */
199 201
 int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
200 202
 				int replicate)
201 203
 {
... ...
@@ -54,6 +54,8 @@
54 54
  *              t_forward_non_ack won't start retransmission on send errors
55 55
  *               anymore (WARNING: callers should release/kill the transaction
56 56
  *               if error is returned) (andrei)
57
+ *  2006-09-15  e2e_cancel uses t_reply_unsafe when called from the 
58
+ *               failure_route and replying to a cancel (andrei)
57 59
  */
58 60
 
59 61
 #include "defs.h"
... ...
@@ -517,19 +519,40 @@ void e2e_cancel( struct sip_msg *cancel_msg,
517 517
 	*/
518 518
 	if (lowest_error<0) {
519 519
 		LOG(L_ERR, "ERROR: cancel error\n");
520
-		t_reply( t_cancel, cancel_msg, 500, "cancel error");
521
-	/* if there are pending branches, let upstream know we
522
-	   are working on it
523
-	*/
520
+		/* if called from failure_route, make sure that the unsafe version
521
+		 * is called (we are already hold the reply mutex for the cancel
522
+		 * transaction).
523
+		 */
524
+		if ((rmode==MODE_ONFAILURE) && (t_cancel==get_t()))
525
+			t_reply_unsafe( t_cancel, cancel_msg, 500, "cancel error");
526
+		else
527
+			t_reply( t_cancel, cancel_msg, 500, "cancel error");
524 528
 	} else if (cancel_bm) {
529
+		/* if there are pending branches, let upstream know we
530
+		   are working on it
531
+		*/
525 532
 		DBG("DEBUG: e2e_cancel: e2e cancel proceeding\n");
526
-		t_reply( t_cancel, cancel_msg, 200, CANCELING );
527
-	/* if the transaction exists, but there is no more pending
528
-	   branch, tell upstream we're done
529
-	*/
533
+		/* if called from failure_route, make sure that the unsafe version
534
+		 * is called (we are already hold the reply mutex for the cancel
535
+		 * transaction).
536
+		 */
537
+		if ((rmode==MODE_ONFAILURE) && (t_cancel==get_t()))
538
+			t_reply_unsafe( t_cancel, cancel_msg, 200, CANCELING );
539
+		else
540
+			t_reply( t_cancel, cancel_msg, 200, CANCELING );
530 541
 	} else {
542
+		/* if the transaction exists, but there is no more pending
543
+		   branch, tell upstream we're done
544
+		*/
531 545
 		DBG("DEBUG: e2e_cancel: e2e cancel -- no more pending branches\n");
532
-		t_reply( t_cancel, cancel_msg, 200, CANCEL_DONE );
546
+		/* if called from failure_route, make sure that the unsafe version
547
+		 * is called (we are already hold the reply mutex for the cancel
548
+		 * transaction).
549
+		 */
550
+		if ((rmode==MODE_ONFAILURE) && (t_cancel==get_t()))
551
+			t_reply_unsafe( t_cancel, cancel_msg, 200, CANCEL_DONE );
552
+		else
553
+			t_reply( t_cancel, cancel_msg, 200, CANCEL_DONE );
533 554
 	}
534 555
 }
535 556
 
... ...
@@ -798,6 +821,10 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
798 798
 	return 1;
799 799
 }
800 800
 
801
+
802
+
803
+/* WARNING: doesn't work from failure route (deadlock, uses t_relay_to which
804
+ *  is failure route unsafe) */
801 805
 int t_replicate(struct sip_msg *p_msg,  struct proxy_l *proxy, int proto )
802 806
 {
803 807
 	/* this is a quite horrible hack -- we just take the message
... ...
@@ -76,9 +76,9 @@
76 76
 
77 77
 struct tm_binds {
78 78
 	register_tmcb_f  register_tmcb;
79
-	cmd_function     t_relay_to_udp;
80
-	cmd_function     t_relay_to_tcp;
81
-	cmd_function     t_relay;
79
+	cmd_function     t_relay_to_udp; /* WARNING: failure_route unsafe */
80
+	cmd_function     t_relay_to_tcp; /* WARNING: failure_route unsafe */ 
81
+	cmd_function     t_relay;        /* WARNING: failure_route unsafe */
82 82
 	tnewtran_f       t_newtran;
83 83
 	treply_f         t_reply;
84 84
 	treply_wb_f      t_reply_with_body;