Browse code

- tm 6xx fixes: when a 6xx is received send a CANCEL on all the branches for which a provisional response was received and then wait for the branches to finish (timeout, 487 from the CANCEL or another final response which "raced" the CANCEL). Branches that did not receive any response (in fact any response >=100) will be "terminated" immediately (fake 487). - tm which_cancel() 0-the cancel bitmap fix - tm which_cancel(), should_cancel(), cancel_branch() enhancements/changes - tm rpc_cancel fixes (it works now)

Andrei Pelinescu-Onciul authored on 10/10/2006 19:21:59
Showing 8 changed files
... ...
@@ -67,7 +67,7 @@ MAIN_NAME=ser
67 67
 VERSION = 0
68 68
 PATCHLEVEL = 10
69 69
 SUBLEVEL =   99
70
-EXTRAVERSION = -dev49-dns_cache
70
+EXTRAVERSION = -dev50-dns_cache
71 71
 
72 72
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
73 73
 			$(SUBLEVEL) )
... ...
@@ -24,7 +24,12 @@ modules:
24 24
                 hashing after an uri (to, from or request uri)
25 25
               - improved uri hashing (password is ignored, port is used only
26 26
                 if != 5060 or 5061)
27
- - tm        - better final reply selection: 6xx is preferred over other 
27
+ - tm        - on 6xx immediately cancel all the branches for which a 
28
+               provisional response was received and wait for all the 
29
+               branches to finish (either timeout, the 487 from the CANCEL
30
+               or a final response still on the wire in the moment the
31
+               CANCEL was sent)
32
+             - better final reply selection: 6xx is preferred over other 
28 33
                negative replies; from several 4xx prefer 401, 407, 415, 420,
29 34
                484 (in this order). For all the other cases, return the lowest
30 35
                code (as before)
... ...
@@ -190,8 +190,10 @@ struct totag_elem {
190 190
 #define T_NOISY_CTIMER_FLAG  (1<<2)
191 191
 /* transaction canceled */
192 192
 #define T_CANCELED           (1<<3)
193
+/* 6xx received => stop forking */
194
+#define T_6xx                (1<<4) 
193 195
 
194
-#define T_IN_AGONY (1<<4) /* set if waiting to die (delete timer)
196
+#define T_IN_AGONY (1<<5) /* set if waiting to die (delete timer)
195 197
                              TODO: replace it with del on unref */
196 198
 
197 199
 /* transaction context */
... ...
@@ -31,6 +31,7 @@
31 31
  *             moved here (jiri)
32 32
  * 2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
33 33
  * 2004-02-13  timer_link.payload removed (bogdan)
34
+ * 2006-10-10  cancel_uacs  & cancel_branch take more options now (andrei)
34 35
  */
35 36
 
36 37
 #include <stdio.h> /* for FILE* in fifo_uac_cancel */
... ...
@@ -53,13 +54,12 @@
53 53
    by two processes might concurrently try to generate
54 54
    a CANCEL for the third branch, resulting in race conditions
55 55
    during writing to cancel buffer
56
-*/
57
-
58
-
56
+ WARNING: - has side effects, see should_cancel_branch() */
59 57
 void which_cancel( struct cell *t, branch_bm_t *cancel_bm )
60 58
 {
61 59
 	int i;
62
-
60
+	
61
+	*cancel_bm=0;
63 62
 	for( i=0 ; i<t->nr_of_outgoings ; i++ ) {
64 63
 		if (should_cancel_branch(t, i)) 
65 64
 			*cancel_bm |= 1<<i ;
... ...
@@ -68,25 +68,67 @@ void which_cancel( struct cell *t, branch_bm_t *cancel_bm )
68 68
 }
69 69
 
70 70
 
71
-/* cancel branches scheduled for deletion */
72
-void cancel_uacs( struct cell *t, branch_bm_t cancel_bm )
71
+
72
+
73
+/* cancel branches scheduled for deletion
74
+ * params: t          - transaction
75
+ *          cancel_bm - bitmap with the branches that are supposed to be 
76
+ *                       canceled 
77
+ *          flags     - how_to_cancel flags, see cancel_branch()
78
+ * returns: bitmap with the still active branches (on fr timer) */
79
+int cancel_uacs( struct cell *t, branch_bm_t cancel_bm, int flags)
73 80
 {
74 81
 	int i;
82
+	int ret;
83
+	int r;
75 84
 
85
+	ret=0;
76 86
 	/* cancel pending client transactions, if any */
77 87
 	for( i=0 ; i<t->nr_of_outgoings ; i++ ) 
78
-		if (cancel_bm & (1<<i))
79
-           	cancel_branch(t, i);
88
+		if (cancel_bm & (1<<i)){
89
+			r=cancel_branch(t, i, flags);
90
+			ret|=(r!=0)<<i;
91
+		}
92
+	return ret;
80 93
 }
81 94
 
82
-void cancel_branch( struct cell *t, int branch )
95
+
96
+
97
+/* 
98
+ * params:  t - transaction
99
+ *          branch - branch number to be canceled
100
+ *          flags - howto cancel: 
101
+ *                   F_CANCEL_B_KILL - will completely stop the 
102
+ *                     branch (stops the timers), use with care
103
+ *                   F_CANCEL_B_FAKE_REPLY - will send a fake 487
104
+ *                      to all branches that haven't received any response
105
+ *                      (>=100). It assumes the REPLY_LOCK is not held
106
+ *                      (if it is => deadlock)
107
+ *                  default: stop only the retransmissions for the branch
108
+ *                      and leave it to timeout if it doesn't receive any
109
+ *                      response to the CANCEL
110
+ * returns: 0 - branch inactive after running cancel_branch() 
111
+ *          1 - branch still active  (fr_timer)
112
+ *         -1 - error
113
+ * WARNING:
114
+ *          - F_CANCEL_KILL_B should be used only if the transaction is killed
115
+ *            explicitely afterwards (since it might kill all the timers
116
+ *            the transaction won't be able to "kill" itself => if not
117
+ *            explicitely "put_on_wait" it migh leave forever)
118
+ *          - F_CANCEL_B_FAKE_REPLY must be used only if the REPLY_LOCK is not
119
+ *            held
120
+ */
121
+int cancel_branch( struct cell *t, int branch, int flags )
83 122
 {
84 123
 	char *cancel;
85 124
 	unsigned int len;
86 125
 	struct retr_buf *crb, *irb;
126
+	int ret;
127
+	branch_bm_t tmp_bm;
87 128
 
88 129
 	crb=&t->uac[branch].local_cancel;
89 130
 	irb=&t->uac[branch].request;
131
+	ret=1;
90 132
 
91 133
 #	ifdef EXTRA_DEBUG
92 134
 	if (crb->buffer!=0 && crb->buffer!=BUSY_BUFFER) {
... ...
@@ -95,25 +137,52 @@ void cancel_branch( struct cell *t, int branch )
95 95
 	}
96 96
 #	endif
97 97
 
98
-	stop_rb_timers( irb );
99
-
100
-	if (t->uac[branch].last_received < 100) {
101
-		DBG("DEBUG: cancel_branch: no response ever received: "
102
-		    "giving up on cancel\n");
103
-		return;
98
+	if (flags & F_CANCEL_B_KILL){
99
+		stop_rb_timers( irb );
100
+		ret=0;
101
+		if (t->uac[branch].last_received < 100) {
102
+			DBG("DEBUG: cancel_branch: no response ever received: "
103
+			    "giving up on cancel\n");
104
+			if (flags & F_CANCEL_B_FAKE_REPLY){
105
+				LOCK_REPLIES(t);
106
+				if (relay_reply(t, FAKED_REPLY, branch, 487, &tmp_bm) == 
107
+										RPS_ERROR){
108
+					return -1;
109
+				}
110
+			}
111
+			/* do nothing, hope that the caller will clean up */
112
+			return ret;
113
+		}
114
+	}else{
115
+		stop_rb_retr(irb); /* stop retransmissions */
116
+		if (t->uac[branch].last_received < 100) {
117
+			/* no response received => don't send a cancel on this branch,
118
+			 *  just drop it */
119
+			if (flags & F_CANCEL_B_FAKE_REPLY){
120
+				stop_rb_timers( irb ); /* stop even the fr timer */
121
+				LOCK_REPLIES(t);
122
+				if (relay_reply(t, FAKED_REPLY, branch, 487, &tmp_bm) == 
123
+										RPS_ERROR){
124
+					return -1;
125
+				}
126
+				return 0; /* should be inactive after the 487 */
127
+			}
128
+			/* do nothing, just wait for the final timeout */
129
+			return 1;
130
+		}
104 131
 	}
105 132
 	
106 133
 	cancel = build_local(t, branch, &len, CANCEL, CANCEL_LEN, &t->to);
107 134
 	if (!cancel) {
108 135
 		LOG(L_ERR, "ERROR: attempt to build a CANCEL failed\n");
109
-		return;
136
+		return -1;
110 137
 	}
111 138
 	/* install cancel now */
112 139
 	crb->buffer = cancel;
113 140
 	crb->buffer_len = len;
114 141
 	crb->dst = irb->dst;
115 142
 	crb->branch = branch;
116
-	/* label it as cancel so that FR timer can better now how to
143
+	/* label it as cancel so that FR timer can better know how to
117 144
 	   deal with it */
118 145
 	crb->activ_type = TYPE_LOCAL_CANCEL;
119 146
 
... ...
@@ -123,6 +192,7 @@ void cancel_branch( struct cell *t, int branch )
123 123
 	if (start_retr( crb )!=0)
124 124
 		LOG(L_CRIT, "BUG: cancel_branch: failed to start retransmission"
125 125
 					" for %p\n", crb);
126
+	return ret;
126 127
 }
127 128
 
128 129
 
... ...
@@ -143,14 +213,17 @@ void rpc_cancel(rpc_t* rpc, void* c)
143 143
 {
144 144
 	struct cell *trans;
145 145
 	static char cseq[128], callid[128];
146
+	branch_bm_t cancel_bm;
147
+	int i,j;
146 148
 
147 149
 	str cseq_s;   /* cseq */
148 150
 	str callid_s; /* callid */
149 151
 
150 152
 	cseq_s.s=cseq;
151 153
 	callid_s.s=callid;
154
+	cancel_bm=0;
152 155
 
153
-	if (rpc->scan(rpc, "SS", &callid_s, &cseq_s) < 2) {
156
+	if (rpc->scan(c, "SS", &callid_s, &cseq_s) < 2) {
154 157
 		rpc->fault(c, 400, "Callid and CSeq expected as parameters");
155 158
 		return;
156 159
 	}
... ...
@@ -160,10 +233,21 @@ void rpc_cancel(rpc_t* rpc, void* c)
160 160
 		rpc->fault(c, 400, "Transaction not found");
161 161
 		return;
162 162
 	}
163
-	     /* tell tm to cancel the call */
163
+	/*  find the branches that need cancel-ing */
164
+	LOCK_REPLIES(trans);
165
+		which_cancel(trans, &cancel_bm);
166
+	UNLOCK_REPLIES(trans);
167
+	 /* tell tm to cancel the call */
164 168
 	DBG("Now calling cancel_uacs\n");
165
-	(*cancel_uacs)(trans, ~0);
169
+	i=cancel_uacs(trans, cancel_bm, 0); /* don't fake 487s, 
170
+										 just wait for timeout */
166 171
 	
167 172
 	     /* t_lookup_callid REF`d the transaction for us, we must UNREF here! */
168 173
 	UNREF(trans);
174
+	j=0;
175
+	while(i){
176
+		j++;
177
+		i&=i-1;
178
+	}
179
+	rpc->add(c, "ds", j, "branches remaining (waiting for timeout)");
169 180
 }
... ...
@@ -28,6 +28,8 @@
28 28
  * History:
29 29
  * ---------
30 30
  *  2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
31
+ *  2006-10-10  should_cancel_branch() returns true even for branches with
32
+ *               no response or with response <100 (andrei)
31 33
  */
32 34
 
33 35
 
... ...
@@ -51,20 +53,36 @@
51 51
 
52 52
 #define BUSY_BUFFER ((char *)-1)
53 53
 
54
+/* flags for cancel_uacs(), cancel_branch() */
55
+#define F_CANCEL_B_KILL 1  /*  will completely stop the  branch (stops the
56
+							   timers), use only before a put_on_wait()
57
+							   or set_final_timer()*/
58
+#define F_CANCEL_B_FAKE_REPLY 2 /* will send a fake 487 to all branches that
59
+								 haven't received any response (>=100). It
60
+								 assumes the REPLY_LOCK is not held (if it is
61
+								 => deadlock) */
62
+
63
+
54 64
 void which_cancel( struct cell *t, branch_bm_t *cancel_bm );
55
-void cancel_uacs( struct cell *t, branch_bm_t cancel_bm );
56
-void cancel_branch( struct cell *t, int branch );
65
+int cancel_uacs( struct cell *t, branch_bm_t cancel_bm, int flags );
66
+int cancel_branch( struct cell *t, int branch, int flags );
67
+
68
+
57 69
 
70
+/* should be called either with the REPLY_LOCK held or if its known
71
+ *  by other means that no other cancel trigerring reply can appear
72
+ *  between this call and the call to cancel_uacs()/cancel_branch()
73
+ *  WARNING: has side effects: marks branches that should be canceled
74
+ *   and a second call won't return them again */
58 75
 inline short static should_cancel_branch( struct cell *t, int b )
59 76
 {
60 77
 	int last_received;
61 78
 	short should;
62 79
 
63 80
 	last_received=t->uac[b].last_received;
64
-	/* cancel only if provisional received and noone else
65
-	   attempted to cancel yet */
66
-	should=last_received>=100 && last_received<200
67
-		&& t->uac[b].local_cancel.buffer==0;
81
+	/* cancel even if no reply received (in this case cancel_branch()
82
+	 *  won't actually send the cancel but it will do the cleanup) */
83
+	should=last_received<200 && t->uac[b].local_cancel.buffer==0;
68 84
 	/* we'll cancel -- label it so that noone else
69 85
 		(e.g. another 200 branch) will try to do the same */
70 86
 	if (should) t->uac[b].local_cancel.buffer=BUSY_BUFFER;
... ...
@@ -56,6 +56,8 @@
56 56
  *               if error is returned) (andrei)
57 57
  *  2006-09-15  e2e_cancel uses t_reply_unsafe when called from the 
58 58
  *               failure_route and replying to a cancel (andrei)
59
+ *  2006-10-10  e2e_cancel update for the new/modified 
60
+ *               which_cancel()/should_cancel() (andrei)
59 61
  */
60 62
 
61 63
 #include "defs.h"
... ...
@@ -477,7 +479,7 @@ void e2e_cancel( struct sip_msg *cancel_msg,
477 477
 	t_cancel->label=t_invite->label;
478 478
 	/* ... and install CANCEL UACs */
479 479
 	for (i=0; i<t_invite->nr_of_outgoings; i++)
480
-		if (cancel_bm & (1<<i)) {
480
+		if ((cancel_bm & (1<<i)) && (t_invite->uac[i].last_received>=100)) {
481 481
 			ret=e2e_cancel_branch(cancel_msg, t_cancel, t_invite, i);
482 482
 			if (ret<0) cancel_bm &= ~(1<<i);
483 483
 			if (ret<lowest_error) lowest_error=ret;
... ...
@@ -489,16 +491,17 @@ void e2e_cancel( struct sip_msg *cancel_msg,
489 489
 	/* send them out */
490 490
 	for (i = 0; i < t_cancel->nr_of_outgoings; i++) {
491 491
 		if (cancel_bm & (1 << i)) {
492
-			     /* Provisional reply received on this branch, send CANCEL */
493
-			     /* No need to stop timers as they have already been stopped by the reply */
494
-			if (SEND_BUFFER(&t_cancel->uac[i].request) == -1) {
495
-				LOG(L_ERR, "ERROR: e2e_cancel: send failed\n");
496
-			}
497
-			if (start_retr( &t_cancel->uac[i].request )!=0)
498
-				LOG(L_CRIT, "BUG: e2e_cancel: failed to start retr. for %p\n",
499
-							&t_cancel->uac[i].request);
500
-		} else {
501
-			if (t_invite->uac[i].last_received < 100) {
492
+			if (t_invite->uac[i].last_received>=100){
493
+				/* Provisional reply received on this branch, send CANCEL */
494
+				/* No need to stop timers as they have already been stopped 
495
+				 * by the reply */
496
+				if (SEND_BUFFER(&t_cancel->uac[i].request) == -1) {
497
+					LOG(L_ERR, "ERROR: e2e_cancel: send failed\n");
498
+				}
499
+				if (start_retr( &t_cancel->uac[i].request )!=0)
500
+					LOG(L_CRIT, "BUG: e2e_cancel: failed to start retr."
501
+							" for %p\n", &t_cancel->uac[i].request);
502
+			} else {
502 503
 				/* No provisional response received, stop
503 504
 				 * retransmission timers */
504 505
 				stop_rb_retr(&t_invite->uac[i].request);
... ...
@@ -406,7 +406,6 @@ static int _reply_light( struct cell *trans, char* buf, unsigned int len,
406 406
 		goto error2;
407 407
 	}
408 408
 
409
-
410 409
 	rb = & trans->uas.response;
411 410
 	rb->activ_type=code;
412 411
 
... ...
@@ -445,7 +444,8 @@ static int _reply_light( struct cell *trans, char* buf, unsigned int len,
445 445
 		}
446 446
 
447 447
 		cleanup_uac_timers( trans );
448
-		if (is_invite(trans)) cancel_uacs( trans, cancel_bitmap );
448
+		if (is_invite(trans)) 
449
+			cancel_uacs( trans, cancel_bitmap, F_CANCEL_B_KILL );
449 450
 		set_final_timer(  trans );
450 451
 	}
451 452
 
... ...
@@ -478,7 +478,8 @@ error2:
478 478
 error:
479 479
 	/* do UAC cleanup */
480 480
 	cleanup_uac_timers( trans );
481
-	if ( is_invite(trans) ) cancel_uacs( trans, cancel_bitmap );
481
+	if ( is_invite(trans) )
482
+		cancel_uacs( trans, cancel_bitmap, F_CANCEL_B_KILL);
482 483
 	/* we did not succeed -- put the transaction on wait */
483 484
 	put_on_wait(trans);
484 485
 	return -1;
... ...
@@ -859,11 +860,13 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
859 859
 			DBG("DEBUG: final reply retransmission\n");
860 860
 			goto discard;
861 861
 		}
862
-		/* if you FR-timed-out, faked a local 408 or 480 and 487 came, don't
862
+		/* if you FR-timed-out, faked a local 408  and 487 came or
863
+		 *  faked a CANCEL on a non-replied branch don't
863 864
 		 * report on it either */
864
-		if ((Trans->uac[branch].last_received==408 ||
865
-				Trans->uac[branch].last_received==480) && new_code==487) {
866
-			DBG("DEBUG: 487 came for a timed-out branch\n");
865
+		if ((Trans->uac[branch].last_received==487) || 
866
+				(Trans->uac[branch].last_received==408 && new_code==487)) {
867
+			DBG("DEBUG: %d came for a %d branch (ignored)\n",
868
+					new_code, Trans->uac[branch].last_received);
867 869
 			goto discard;
868 870
 		}
869 871
 		/* this looks however how a very strange status rewrite attempt;
... ...
@@ -886,6 +889,13 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
886 886
 		if (picked_branch==-2) { /* branches open yet */
887 887
 			*should_store=1;
888 888
 			*should_relay=-1;
889
+			if (new_code>=600 && new_code<=699){
890
+				if (!(Trans->flags & T_6xx)){
891
+					/* cancel only the first time we get a 6xx */
892
+					which_cancel(Trans, cancel_bitmap);
893
+					Trans->flags|=T_6xx;
894
+				}
895
+			}
889 896
 			return RPS_STORE;
890 897
 		}
891 898
 		if (picked_branch==-1) {
... ...
@@ -901,6 +911,8 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
901 901
 		 * make it available in failure routes - a kind of "fake"
902 902
 		 * save of the final reply per branch */
903 903
 		Trans->uac[branch].reply = reply;
904
+		Trans->flags&=~T_6xx; /* clear the 6xx flag , we want to 
905
+								 allow new branches from the failure route */
904 906
 
905 907
 		/* run ON_FAILURE handlers ( route and callbacks) */
906 908
 		if ( has_tran_tmcbs( Trans, TMCB_ON_FAILURE_RO|TMCB_ON_FAILURE)
... ...
@@ -1282,7 +1294,7 @@ error02:
1282 1282
 error01:
1283 1283
 	t_reply_unsafe( t, t->uas.request, 500, "Reply processing error" );
1284 1284
 	UNLOCK_REPLIES(t);
1285
-	if (is_invite(t)) cancel_uacs( t, *cancel_bitmap );
1285
+	if (is_invite(t)) cancel_uacs( t, *cancel_bitmap, 0);
1286 1286
 	/* a serious error occurred -- attempt to send an error reply;
1287 1287
 	   it will take care of clean-ups  */
1288 1288
 
... ...
@@ -1364,7 +1376,7 @@ error:
1364 1364
 	cleanup_uac_timers(t);
1365 1365
 	if ( get_cseq(p_msg)->method.len==INVITE_LEN
1366 1366
 		&& memcmp( get_cseq(p_msg)->method.s, INVITE, INVITE_LEN)==0)
1367
-		cancel_uacs( t, *cancel_bitmap );
1367
+		cancel_uacs( t, *cancel_bitmap, F_CANCEL_B_KILL);
1368 1368
 	put_on_wait(t);
1369 1369
 	return RPS_ERROR;
1370 1370
 }
... ...
@@ -1493,10 +1505,15 @@ int reply_received( struct sip_msg  *p_msg )
1493 1493
 			      * be still pending branches ...
1494 1494
 			      */
1495 1495
 			cleanup_uac_timers( t );
1496
-			if (is_invite(t)) cancel_uacs( t, cancel_bitmap );
1496
+			if (is_invite(t)) cancel_uacs(t, cancel_bitmap, F_CANCEL_B_KILL);
1497 1497
 			/* There is no need to call set_final_timer because we know
1498
->--->--->--- * that the transaction is local */
1498
+			 * that the transaction is local */
1499 1499
 			put_on_wait(t);
1500
+		}else if (cancel_bitmap){
1501
+			/* cancel everything, even non-INVITEs (e.g in case of 6xx), wait
1502
+			 * for the cancel replies if a provisional response was received
1503
+			 *  or generate a fake reply if not */
1504
+			cancel_uacs(t, cancel_bitmap, F_CANCEL_B_FAKE_REPLY);
1500 1505
 		}
1501 1506
 	} else {
1502 1507
 		reply_status=relay_reply( t, p_msg, branch, msg_status,
... ...
@@ -1506,12 +1523,20 @@ int reply_received( struct sip_msg  *p_msg )
1506 1506
 				be still pending branches ...
1507 1507
 			     */
1508 1508
 			cleanup_uac_timers( t );
1509
-			if (is_invite(t)) cancel_uacs( t, cancel_bitmap );
1509
+			/* 2xx is a special case: we can have a COMPLETED request
1510
+			 * with branches still open => we have to cancel them */
1511
+			if (is_invite(t) && cancel_bitmap) 
1512
+				cancel_uacs( t, cancel_bitmap,  F_CANCEL_B_KILL);
1510 1513
 			/* FR for negative INVITES, WAIT anything else */
1511 1514
 			/* Call to set_final_timer is embedded in relay_reply to avoid
1512 1515
 			 * race conditions when reply is sent out and an ACK to stop
1513 1516
 			 * retransmissions comes before retransmission timer is set.*/
1514 1517
 			/* set_final_timer(t) */
1518
+		}else if (cancel_bitmap){
1519
+			/* cancel everything, even non-INVITEs (e.g in case of 6xx), wait
1520
+			 * for the cancel replies if a provisional response was received
1521
+			 *  or generate a fake reply if not */
1522
+			cancel_uacs(t, cancel_bitmap, F_CANCEL_B_FAKE_REPLY);
1515 1523
 		}
1516 1524
 	}
1517 1525
 	uac->request.flags|=F_RB_REPLIED;
... ...
@@ -243,8 +243,6 @@ static void fake_reply(struct cell *t, int branch, int code )
243 243
 	enum rps reply_status;
244 244
 
245 245
 	do_cancel_branch = is_invite(t) && should_cancel_branch(t, branch);
246
-
247
-	cancel_bitmap=do_cancel_branch ? 1<<branch : 0;
248 246
 	if ( is_local(t) ) {
249 247
 		reply_status=local_reply( t, FAKED_REPLY, branch, 
250 248
 					  code, &cancel_bitmap );
... ...
@@ -276,7 +274,7 @@ static void fake_reply(struct cell *t, int branch, int code )
276 276
 
277 277
 	}
278 278
 	/* now when out-of-lock do the cancel I/O */
279
-	if (do_cancel_branch) cancel_branch(t, branch );
279
+	if (do_cancel_branch) cancel_branch(t, branch, 0);
280 280
 	/* it's cleaned up on error; if no error occurred and transaction
281 281
 	   completed regularly, I have to clean-up myself
282 282
 	*/