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 54
    by two processes might concurrently try to generate
54 55
    a CANCEL for the third branch, resulting in race conditions
55 56
    during writing to cancel buffer
56
-*/
57
-
58
-
57
+ WARNING: - has side effects, see should_cancel_branch() */
59 58
 void which_cancel( struct cell *t, branch_bm_t *cancel_bm )
60 59
 {
61 60
 	int i;
62
-
61
+	
62
+	*cancel_bm=0;
63 63
 	for( i=0 ; i<t->nr_of_outgoings ; i++ ) {
64 64
 		if (should_cancel_branch(t, i)) 
65 65
 			*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 137
 	}
96 138
 #	endif
97 139
 
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;
140
+	if (flags & F_CANCEL_B_KILL){
141
+		stop_rb_timers( irb );
142
+		ret=0;
143
+		if (t->uac[branch].last_received < 100) {
144
+			DBG("DEBUG: cancel_branch: no response ever received: "
145
+			    "giving up on cancel\n");
146
+			if (flags & F_CANCEL_B_FAKE_REPLY){
147
+				LOCK_REPLIES(t);
148
+				if (relay_reply(t, FAKED_REPLY, branch, 487, &tmp_bm) == 
149
+										RPS_ERROR){
150
+					return -1;
151
+				}
152
+			}
153
+			/* do nothing, hope that the caller will clean up */
154
+			return ret;
155
+		}
156
+	}else{
157
+		stop_rb_retr(irb); /* stop retransmissions */
158
+		if (t->uac[branch].last_received < 100) {
159
+			/* no response received => don't send a cancel on this branch,
160
+			 *  just drop it */
161
+			if (flags & F_CANCEL_B_FAKE_REPLY){
162
+				stop_rb_timers( irb ); /* stop even the fr timer */
163
+				LOCK_REPLIES(t);
164
+				if (relay_reply(t, FAKED_REPLY, branch, 487, &tmp_bm) == 
165
+										RPS_ERROR){
166
+					return -1;
167
+				}
168
+				return 0; /* should be inactive after the 487 */
169
+			}
170
+			/* do nothing, just wait for the final timeout */
171
+			return 1;
172
+		}
104 173
 	}
105 174
 	
106 175
 	cancel = build_local(t, branch, &len, CANCEL, CANCEL_LEN, &t->to);
107 176
 	if (!cancel) {
108 177
 		LOG(L_ERR, "ERROR: attempt to build a CANCEL failed\n");
109
-		return;
178
+		return -1;
110 179
 	}
111 180
 	/* install cancel now */
112 181
 	crb->buffer = cancel;
113 182
 	crb->buffer_len = len;
114 183
 	crb->dst = irb->dst;
115 184
 	crb->branch = branch;
116
-	/* label it as cancel so that FR timer can better now how to
185
+	/* label it as cancel so that FR timer can better know how to
117 186
 	   deal with it */
118 187
 	crb->activ_type = TYPE_LOCAL_CANCEL;
119 188
 
... ...
@@ -123,6 +192,7 @@ void cancel_branch( struct cell *t, int branch )
123 192
 	if (start_retr( crb )!=0)
124 193
 		LOG(L_CRIT, "BUG: cancel_branch: failed to start retransmission"
125 194
 					" for %p\n", crb);
195
+	return ret;
126 196
 }
127 197
 
128 198
 
... ...
@@ -143,14 +213,17 @@ void rpc_cancel(rpc_t* rpc, void* c)
143 213
 {
144 214
 	struct cell *trans;
145 215
 	static char cseq[128], callid[128];
216
+	branch_bm_t cancel_bm;
217
+	int i,j;
146 218
 
147 219
 	str cseq_s;   /* cseq */
148 220
 	str callid_s; /* callid */
149 221
 
150 222
 	cseq_s.s=cseq;
151 223
 	callid_s.s=callid;
224
+	cancel_bm=0;
152 225
 
153
-	if (rpc->scan(rpc, "SS", &callid_s, &cseq_s) < 2) {
226
+	if (rpc->scan(c, "SS", &callid_s, &cseq_s) < 2) {
154 227
 		rpc->fault(c, 400, "Callid and CSeq expected as parameters");
155 228
 		return;
156 229
 	}
... ...
@@ -160,10 +233,21 @@ void rpc_cancel(rpc_t* rpc, void* c)
160 233
 		rpc->fault(c, 400, "Transaction not found");
161 234
 		return;
162 235
 	}
163
-	     /* tell tm to cancel the call */
236
+	/*  find the branches that need cancel-ing */
237
+	LOCK_REPLIES(trans);
238
+		which_cancel(trans, &cancel_bm);
239
+	UNLOCK_REPLIES(trans);
240
+	 /* tell tm to cancel the call */
164 241
 	DBG("Now calling cancel_uacs\n");
165
-	(*cancel_uacs)(trans, ~0);
242
+	i=cancel_uacs(trans, cancel_bm, 0); /* don't fake 487s, 
243
+										 just wait for timeout */
166 244
 	
167 245
 	     /* t_lookup_callid REF`d the transaction for us, we must UNREF here! */
168 246
 	UNREF(trans);
247
+	j=0;
248
+	while(i){
249
+		j++;
250
+		i&=i-1;
251
+	}
252
+	rpc->add(c, "ds", j, "branches remaining (waiting for timeout)");
169 253
 }
... ...
@@ -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 53
 
52 54
 #define BUSY_BUFFER ((char *)-1)
53 55
 
56
+/* flags for cancel_uacs(), cancel_branch() */
57
+#define F_CANCEL_B_KILL 1  /*  will completely stop the  branch (stops the
58
+							   timers), use only before a put_on_wait()
59
+							   or set_final_timer()*/
60
+#define F_CANCEL_B_FAKE_REPLY 2 /* will send a fake 487 to all branches that
61
+								 haven't received any response (>=100). It
62
+								 assumes the REPLY_LOCK is not held (if it is
63
+								 => deadlock) */
64
+
65
+
54 66
 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 );
67
+int cancel_uacs( struct cell *t, branch_bm_t cancel_bm, int flags );
68
+int cancel_branch( struct cell *t, int branch, int flags );
69
+
70
+
57 71
 
72
+/* should be called either with the REPLY_LOCK held or if its known
73
+ *  by other means that no other cancel trigerring reply can appear
74
+ *  between this call and the call to cancel_uacs()/cancel_branch()
75
+ *  WARNING: has side effects: marks branches that should be canceled
76
+ *   and a second call won't return them again */
58 77
 inline short static should_cancel_branch( struct cell *t, int b )
59 78
 {
60 79
 	int last_received;
61 80
 	short should;
62 81
 
63 82
 	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;
83
+	/* cancel even if no reply received (in this case cancel_branch()
84
+	 *  won't actually send the cancel but it will do the cleanup) */
85
+	should=last_received<200 && t->uac[b].local_cancel.buffer==0;
68 86
 	/* we'll cancel -- label it so that noone else
69 87
 		(e.g. another 200 branch) will try to do the same */
70 88
 	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 479
 	t_cancel->label=t_invite->label;
478 480
 	/* ... and install CANCEL UACs */
479 481
 	for (i=0; i<t_invite->nr_of_outgoings; i++)
480
-		if (cancel_bm & (1<<i)) {
482
+		if ((cancel_bm & (1<<i)) && (t_invite->uac[i].last_received>=100)) {
481 483
 			ret=e2e_cancel_branch(cancel_msg, t_cancel, t_invite, i);
482 484
 			if (ret<0) cancel_bm &= ~(1<<i);
483 485
 			if (ret<lowest_error) lowest_error=ret;
... ...
@@ -489,16 +491,17 @@ void e2e_cancel( struct sip_msg *cancel_msg,
489 491
 	/* send them out */
490 492
 	for (i = 0; i < t_cancel->nr_of_outgoings; i++) {
491 493
 		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) {
494
+			if (t_invite->uac[i].last_received>=100){
495
+				/* Provisional reply received on this branch, send CANCEL */
496
+				/* No need to stop timers as they have already been stopped 
497
+				 * by the reply */
498
+				if (SEND_BUFFER(&t_cancel->uac[i].request) == -1) {
499
+					LOG(L_ERR, "ERROR: e2e_cancel: send failed\n");
500
+				}
501
+				if (start_retr( &t_cancel->uac[i].request )!=0)
502
+					LOG(L_CRIT, "BUG: e2e_cancel: failed to start retr."
503
+							" for %p\n", &t_cancel->uac[i].request);
504
+			} else {
502 505
 				/* No provisional response received, stop
503 506
 				 * retransmission timers */
504 507
 				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 444
 		}
446 445
 
447 446
 		cleanup_uac_timers( trans );
448
-		if (is_invite(trans)) cancel_uacs( trans, cancel_bitmap );
447
+		if (is_invite(trans)) 
448
+			cancel_uacs( trans, cancel_bitmap, F_CANCEL_B_KILL );
449 449
 		set_final_timer(  trans );
450 450
 	}
451 451
 
... ...
@@ -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 860
 			DBG("DEBUG: final reply retransmission\n");
860 861
 			goto discard;
861 862
 		}
862
-		/* if you FR-timed-out, faked a local 408 or 480 and 487 came, don't
863
+		/* if you FR-timed-out, faked a local 408  and 487 came or
864
+		 *  faked a CANCEL on a non-replied branch don't
863 865
 		 * 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");
866
+		if ((Trans->uac[branch].last_received==487) || 
867
+				(Trans->uac[branch].last_received==408 && new_code==487)) {
868
+			DBG("DEBUG: %d came for a %d branch (ignored)\n",
869
+					new_code, Trans->uac[branch].last_received);
867 870
 			goto discard;
868 871
 		}
869 872
 		/* 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 889
 		if (picked_branch==-2) { /* branches open yet */
887 890
 			*should_store=1;
888 891
 			*should_relay=-1;
892
+			if (new_code>=600 && new_code<=699){
893
+				if (!(Trans->flags & T_6xx)){
894
+					/* cancel only the first time we get a 6xx */
895
+					which_cancel(Trans, cancel_bitmap);
896
+					Trans->flags|=T_6xx;
897
+				}
898
+			}
889 899
 			return RPS_STORE;
890 900
 		}
891 901
 		if (picked_branch==-1) {
... ...
@@ -901,6 +911,8 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
901 911
 		 * make it available in failure routes - a kind of "fake"
902 912
 		 * save of the final reply per branch */
903 913
 		Trans->uac[branch].reply = reply;
914
+		Trans->flags&=~T_6xx; /* clear the 6xx flag , we want to 
915
+								 allow new branches from the failure route */
904 916
 
905 917
 		/* run ON_FAILURE handlers ( route and callbacks) */
906 918
 		if ( has_tran_tmcbs( Trans, TMCB_ON_FAILURE_RO|TMCB_ON_FAILURE)
... ...
@@ -1282,7 +1294,7 @@ error02:
1282 1294
 error01:
1283 1295
 	t_reply_unsafe( t, t->uas.request, 500, "Reply processing error" );
1284 1296
 	UNLOCK_REPLIES(t);
1285
-	if (is_invite(t)) cancel_uacs( t, *cancel_bitmap );
1297
+	if (is_invite(t)) cancel_uacs( t, *cancel_bitmap, 0);
1286 1298
 	/* a serious error occurred -- attempt to send an error reply;
1287 1299
 	   it will take care of clean-ups  */
1288 1300
 
... ...
@@ -1364,7 +1376,7 @@ error:
1364 1376
 	cleanup_uac_timers(t);
1365 1377
 	if ( get_cseq(p_msg)->method.len==INVITE_LEN
1366 1378
 		&& memcmp( get_cseq(p_msg)->method.s, INVITE, INVITE_LEN)==0)
1367
-		cancel_uacs( t, *cancel_bitmap );
1379
+		cancel_uacs( t, *cancel_bitmap, F_CANCEL_B_KILL);
1368 1380
 	put_on_wait(t);
1369 1381
 	return RPS_ERROR;
1370 1382
 }
... ...
@@ -1493,10 +1505,15 @@ int reply_received( struct sip_msg  *p_msg )
1493 1505
 			      * be still pending branches ...
1494 1506
 			      */
1495 1507
 			cleanup_uac_timers( t );
1496
-			if (is_invite(t)) cancel_uacs( t, cancel_bitmap );
1508
+			if (is_invite(t)) cancel_uacs(t, cancel_bitmap, F_CANCEL_B_KILL);
1497 1509
 			/* There is no need to call set_final_timer because we know
1498
->--->--->--- * that the transaction is local */
1510
+			 * that the transaction is local */
1499 1511
 			put_on_wait(t);
1512
+		}else if (cancel_bitmap){
1513
+			/* cancel everything, even non-INVITEs (e.g in case of 6xx), wait
1514
+			 * for the cancel replies if a provisional response was received
1515
+			 *  or generate a fake reply if not */
1516
+			cancel_uacs(t, cancel_bitmap, F_CANCEL_B_FAKE_REPLY);
1500 1517
 		}
1501 1518
 	} else {
1502 1519
 		reply_status=relay_reply( t, p_msg, branch, msg_status,
... ...
@@ -1506,12 +1523,20 @@ int reply_received( struct sip_msg  *p_msg )
1506 1523
 				be still pending branches ...
1507 1524
 			     */
1508 1525
 			cleanup_uac_timers( t );
1509
-			if (is_invite(t)) cancel_uacs( t, cancel_bitmap );
1526
+			/* 2xx is a special case: we can have a COMPLETED request
1527
+			 * with branches still open => we have to cancel them */
1528
+			if (is_invite(t) && cancel_bitmap) 
1529
+				cancel_uacs( t, cancel_bitmap,  F_CANCEL_B_KILL);
1510 1530
 			/* FR for negative INVITES, WAIT anything else */
1511 1531
 			/* Call to set_final_timer is embedded in relay_reply to avoid
1512 1532
 			 * race conditions when reply is sent out and an ACK to stop
1513 1533
 			 * retransmissions comes before retransmission timer is set.*/
1514 1534
 			/* set_final_timer(t) */
1535
+		}else if (cancel_bitmap){
1536
+			/* cancel everything, even non-INVITEs (e.g in case of 6xx), wait
1537
+			 * for the cancel replies if a provisional response was received
1538
+			 *  or generate a fake reply if not */
1539
+			cancel_uacs(t, cancel_bitmap, F_CANCEL_B_FAKE_REPLY);
1515 1540
 		}
1516 1541
 	}
1517 1542
 	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 274
 
277 275
 	}
278 276
 	/* now when out-of-lock do the cancel I/O */
279
-	if (do_cancel_branch) cancel_branch(t, branch );
277
+	if (do_cancel_branch) cancel_branch(t, branch, 0);
280 278
 	/* it's cleaned up on error; if no error occurred and transaction
281 279
 	   completed regularly, I have to clean-up myself
282 280
 	*/