Browse code

merge!

Bogdan-Andrei Iancu authored on 26/02/2002 18:44:32
Showing 10 changed files
... ...
@@ -80,8 +80,8 @@ DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
80 80
 	 -DOS='"$(OS)"' -DCOMPILER='"$(CC_VER)"'\
81 81
 	 -DDNS_IP_HACK  -DPKG_MALLOC -DSHM_MEM  -DSHM_MMAP \
82 82
 	 -DF_MALLOC  -DUSE_SYNONIM\
83
+	 -DWAIT -DNEW_HNAME -DNOISY_REPLIES -DSRL\
83 84
 	 -DNO_DEBUG \
84
-	 -DWAIT -DNEW_HNAME -DNOISY_REPLIES -DSRL
85 85
 	 #-DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=0 \
86 86
 	 #-DNOSMP \
87 87
 	 #-DEXTRA_DEBUG 
... ...
@@ -21,7 +21,8 @@ void free_cell( struct cell* dead_cell )
21 21
 	shm_lock();
22 22
 	if ( dead_cell->inbound_request )
23 23
 		sip_msg_free_unsafe( dead_cell->inbound_request );
24
-	if (b=dead_cell->outbound_response.retr_buffer) shm_free_unsafe( b );
24
+	if (b=dead_cell->outbound_response.retr_buffer)
25
+		shm_free_unsafe( b );
25 26
 
26 27
 	/* UA Clients */
27 28
 	for ( i =0 ; i<dead_cell->nr_of_outgoings;  i++ )
... ...
@@ -36,12 +37,15 @@ void free_cell( struct cell* dead_cell )
36 37
 		/* outbound ACKs, if any */
37 38
 		if (rb=dead_cell->outbound_ack[i] )
38 39
 			shm_free_unsafe( rb );
39
-		/* outbound requests*/
40
+		/* local cancel , if any */
41
+		if (rb=dead_cell->outbound_cancel[i] )
42
+			shm_free_unsafe( rb );
43
+		/* inbound response */
40 44
 		if ( dead_cell -> inbound_response[i] )
41
-		sip_msg_free_unsafe( dead_cell->inbound_response[i] );
45
+			sip_msg_free_unsafe( dead_cell->inbound_response[i] );
42 46
 	}
43 47
 	/* mutex */
44
-	/* release_cell_lock( dead_cell ); */
48
+	/* release_cell_lock( dead_celle ); */
45 49
 	/* the cell's body */
46 50
 	shm_free_unsafe( dead_cell );
47 51
 	shm_unlock();
... ...
@@ -32,7 +32,10 @@ struct timer;
32 32
 
33 33
 
34 34
 #define NO_CANCEL       ( (struct retrans_buff*) 0 )
35
-#define EXTERNAL_CANCEL ( (struct retarbs_buff*) -1)
35
+#define EXTERNAL_CANCEL ( (struct retrans_buff*) -1)
36
+
37
+#define STATUS_LOCAL_CANCEL -1
38
+#define STATUS_REQUEST       0
36 39
 
37 40
 
38 41
 typedef struct retrans_buff
... ...
@@ -49,10 +52,13 @@ typedef struct retrans_buff
49 52
 
50 53
 	/*the cell that containes this retrans_buff*/
51 54
 	struct cell* my_T;
55
+	unsigned int branch;
52 56
 
53 57
 	enum lists retr_list;
54
-	/* set to status code if the buffer is a reply, 0 if request */
55
-	int reply;
58
+
59
+	/* set to status code if the buffer is a reply, 
60
+	0 if request or -1 if local CANCEL */
61
+	int status;
56 62
 
57 63
 }retrans_buff_type;
58 64
 
... ...
@@ -134,35 +134,32 @@ int tm_startup()
134 134
 
135 135
 void tm_shutdown()
136 136
 {
137
-    struct timer_link  *tl, *end, *tmp;
138
-    int i;
137
+	struct timer_link  *tl, *end, *tmp;
138
+	int i;
139 139
 
140
-    DBG("DEBUG: tm_shutdown : start\n");
141
-    /*remember the DELETE LIST */
142
-    tl = hash_table->timers[DELETE_LIST].first_tl.next_tl;
140
+	DBG("DEBUG: tm_shutdown : start\n");
141
+	/* remember the DELETE LIST */
142
+	tl = hash_table->timers[DELETE_LIST].first_tl.next_tl;
143 143
 	end = & hash_table->timers[DELETE_LIST].last_tl;
144
-    /*unlink the lists*/
145
-    for( i=0; i<NR_OF_TIMER_LISTS ; i++ )
146
-    {
147
-       //lock( hash_table->timers[i].mutex );
144
+	/* unlink the timer lists */
145
+	for( i=0; i<NR_OF_TIMER_LISTS ; i++ )
148 146
 		reset_timer_list( hash_table, i );
149
-       //unlock( hash_table->timers[i].mutex );
150
-    }
151 147
 
152
-    DBG("DEBUG: tm_shutdown : empting DELETE list\n");
153
-    /* deletes all cells from DELETE_LIST list (they are no more accessible from enrys) */
148
+	DBG("DEBUG: tm_shutdown : empting DELETE list\n");
149
+	/* deletes all cells from DELETE_LIST list
150
+	(they are no more accessible from enrys) */
154 151
 	while (tl!=end) {
155 152
 		tmp=tl->next_tl;
156 153
 		free_cell((struct cell*)tl->payload);
157 154
 		 tl=tmp;
158 155
 	}
159 156
 
160
-    /* destroy the hash table */
161
-    DBG("DEBUG: tm_shutdown : empting hash table\n");
162
-    free_hash_table( hash_table );
163
-    DBG("DEBUG: tm_shutdown : removing semaphores\n");
157
+	/* destroy the hash table */
158
+	DBG("DEBUG: tm_shutdown : empting hash table\n");
159
+	free_hash_table( hash_table );
160
+	DBG("DEBUG: tm_shutdown : removing semaphores\n");
164 161
 	lock_cleanup();
165
-    DBG("DEBUG: tm_shutdown : done\n");
162
+	DBG("DEBUG: tm_shutdown : done\n");
166 163
 }
167 164
 
168 165
 
... ...
@@ -174,42 +171,34 @@ void tm_shutdown()
174 171
  */
175 172
 int t_add_transaction( struct sip_msg* p_msg )
176 173
 {
177
-   struct cell*    new_cell;
178
-
179
-   DBG("DEBUG: t_add_transaction: adding......\n");
174
+	struct cell*    new_cell;
180 175
 
181
-   /* sanity check: ACKs can never establish a transaction */
182
-   if ( p_msg->REQ_METHOD==METHOD_ACK )
183
-   {
184
-       LOG(L_ERR, "ERROR: add_transaction: ACK can't be used to add transaction\n");
185
-      return -1;
186
-   }
176
+	DBG("DEBUG: t_add_transaction: adding......\n");
187 177
 
188
-   /* it's about the same transaction or not?*/
189
-	/* if (t_check( p_msg , 0 )==-1) return -1; */
178
+	/* sanity check: ACKs can never establish a transaction */
179
+	if ( p_msg->REQ_METHOD==METHOD_ACK )
180
+	{
181
+		LOG(L_ERR, "ERROR: add_transaction: ACK can't be used to add"
182
+			" transaction\n");
183
+		return -1;
184
+	}
190 185
 
191
-   /* if the lookup's result is not 0 means that it's a retransmission */
192
-   /* if ( T )
193
-   {
194
-      LOG(L_ERR,"ERROR: t_add_transaction: won't add a retransmission\n");
195
-      return -1;
196
-   } */
197
-
198
-   /* creates a new transaction */
199
-   new_cell = build_cell( p_msg ) ;
200
-   DBG("DEBUG: t_add_transaction: new transaction created %p\n", new_cell);
201
-   if  ( !new_cell ){
202
-	   LOG(L_ERR, "ERROR: add_transaction: out of mem:\n");
203
-	   sh_status();
204
-      return -1;
186
+	/* creates a new transaction */
187
+	new_cell = build_cell( p_msg ) ;
188
+	DBG("DEBUG: t_add_transaction: new transaction created %p\n", new_cell);
189
+	if  ( !new_cell ){
190
+		LOG(L_ERR, "ERROR: add_transaction: out of mem:\n");
191
+		sh_status();
192
+		return -1;
205 193
 	}
206
-   /*insert the transaction into hash table*/
207
-   insert_into_hash_table( hash_table , new_cell );
208
-   DBG("DEBUG: t_add_transaction: new transaction inserted, hash: %d\n", new_cell->hash_index );
194
+	/*insert the transaction into hash table*/
195
+	insert_into_hash_table( hash_table , new_cell );
196
+	DBG("DEBUG: t_add_transaction: new transaction inserted, hash: %d\n",
197
+		new_cell->hash_index );
209 198
 
210
-   T = new_cell;
199
+	T = new_cell;
211 200
 	T_REF(T);
212
-   return 1;
201
+	return 1;
213 202
 }
214 203
 
215 204
 
... ...
@@ -223,28 +212,16 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
223 212
 {
224 213
 	unsigned int  dest_ip     = dest_ip_param;
225 214
 	unsigned int  dest_port  = dest_port_param;
226
-	int                  branch;
215
+	int           branch;
227 216
 	unsigned int  len;
228
-	char               *buf, *shbuf;
217
+	char         *buf, *shbuf;
229 218
 	struct retrans_buff  *rb;
230
-	struct cell      *T_source = T;
219
+	struct cell  *T_source = T;
231 220
 
232 221
 	buf=NULL;
233 222
 	shbuf = NULL;
234 223
 	branch = 0;	/* we don't do any forking right now */
235 224
 
236
-	/* it's about the same transaction or not? */
237
-	/* if (t_check( p_msg , 0 )==-1) return -1; */
238
-
239
-	/*if T hasn't been found after all -> return not found (error) */
240
-	/*
241
-	if ( !T )
242
-	{
243
-		DBG("DEBUG: t_forward: no transaction found for request forwarding\n");
244
-		return -1;
245
-	}
246
-	*/
247
-
248 225
 	/*if it's an ACK and the status is not final or is final, but error the
249 226
 	ACK is not forwarded*/
250 227
 	if ( p_msg->REQ_METHOD==METHOD_ACK  && (T->status/100)!=2 ) {
... ...
@@ -252,10 +229,10 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
252 229
 		return 1;
253 230
 	}
254 231
 
255
-	/* if it's forwarded for the first time ; else the request is retransmited
256
-	 * from the transaction buffer
257
-	 * when forwarding an ACK, this condition will be all the time false because
258
-	 * the forwarded INVITE is in the retransmission buffer */
232
+	/* if it's forwarded for the first time, else the request is retransmited
233
+	from the transaction buffer when forwarding an ACK, this condition will
234
+	be all the time false because the forwarded INVITE is in the
235
+	retransmission buffer */
259 236
 	if ( T->outbound_request[branch]==NULL )
260 237
 	{
261 238
 		DBG("DEBUG: t_forward: first time forwarding\n");
... ...
@@ -263,6 +240,12 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
263 240
 		if ( p_msg->REQ_METHOD==METHOD_CANCEL  )
264 241
 		{
265 242
 			DBG("DEBUG: t_forward: it's CANCEL\n");
243
+			if (T->outgoing_cancel[branch]!=NO_CANCEL)
244
+			{
245
+				DBG("DEBUG: t_forward: CANCEL already send on this branch ->"
246
+					" dropping current CANCEL!!\n");
247
+				return 1;
248
+			}
266 249
 			/* find original cancelled transaction; if found, use its
267 250
 			   next-hops; otherwise use those passed by script */
268 251
 			if (T->T_canceled==T_UNDEFINED)
... ...
@@ -304,8 +287,8 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
304 287
 		/* allocates a new retrans_buff for the outbound request */
305 288
 		DBG("DEBUG: t_forward: building outbound request\n");
306 289
 		shm_lock();
307
-		T->outbound_request[branch] = rb =
308
-			(struct retrans_buff*)shm_malloc_unsafe( sizeof(struct retrans_buff)  );
290
+		T->outbound_request[branch] = rb = (struct retrans_buff*)
291
+			shm_malloc_unsafe(sizeof(struct retrans_buff));
309 292
 		if (!rb)
310 293
 		{
311 294
 			LOG(L_ERR, "ERROR: t_forward: out of shmem\n");
... ...
@@ -328,12 +311,14 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
328 311
 		rb->fr_timer.payload =  rb;
329 312
 		rb->to.sin_family = AF_INET;
330 313
 		rb->my_T =  T;
314
+		rb->branch = branch;
331 315
 		T->nr_of_outgoings = 1;
332 316
 		rb->bufflen = len ;
333 317
 		memcpy( rb->retr_buffer , buf , len );
334 318
 		free( buf ) ; buf=NULL;
335 319
 
336
-		DBG("DEBUG: t_forward: starting timers (retrans and FR) %d\n",get_ticks() );
320
+		DBG("DEBUG: t_forward: starting timers (retrans and FR) %d\n",
321
+			get_ticks() );
337 322
 		/*sets and starts the FINAL RESPONSE timer */
338 323
 		set_timer( hash_table, &(rb->fr_timer), FR_TIMER_LIST );
339 324
 
... ...
@@ -357,13 +342,14 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
357 342
 	{
358 343
 		DBG("DEBUG: t_forward: forwarding CANCEL \n");
359 344
 		/* if no transaction to CANCEL
360
-		    or if the canceled transaction has a final status -> drop the CANCEL*/
345
+		or if the canceled transaction has a final status -> drop the CANCEL*/
361 346
 		if ( T->T_canceled!=T_NULL && T->T_canceled->status>=200)
362 347
 		{
363 348
 			reset_timer( hash_table, &(rb->fr_timer ));
364 349
 			reset_timer( hash_table, &(rb->retr_timer ));
365 350
 			return 1;
366 351
 		}
352
+		T->outgoing_cancel = EXTERNAL_CANCEL;
367 353
 	}
368 354
 
369 355
 	/* send the request */
... ...
@@ -412,7 +398,7 @@ int t_forward_uri( struct sip_msg* p_msg  )
412 398
 int t_on_request_received( struct sip_msg  *p_msg , 
413 399
 	unsigned int ip , unsigned int port)
414 400
 {
415
-	if ( t_check( p_msg , 0 ) )
401
+	if ( t_check( p_msg , 0 , 0 ) )
416 402
 	{
417 403
 		if ( p_msg->first_line.u.request.method_value==METHOD_ACK )
418 404
 		{
... ...
@@ -495,25 +481,14 @@ int t_on_request_received_uri( struct sip_msg  *p_msg )
495 481
 
496 482
 
497 483
 /*   returns 1 if everything was OK or -1 for error
498
-  */
484
+*/
499 485
 int t_release_transaction( struct sip_msg* p_msg)
500 486
 {
501
-/*
502
-	if (t_check( p_msg  , 0 )==-1) return 1;
503
-
504
-   if ( T && T!=T_UNDEFINED )
505
-*/
506 487
       return t_put_on_wait( T );
507
-
508
-/*   return 1; */
509 488
 }
510 489
 
511 490
 
512 491
 
513
-
514
-
515
-
516
-
517 492
 int t_unref( /* struct sip_msg* p_msg */ )
518 493
 {
519 494
 	if (T==T_UNDEFINED || T==T_NULL)
... ...
@@ -527,23 +502,16 @@ int t_unref( /* struct sip_msg* p_msg */ )
527 502
 
528 503
 
529 504
 
530
-
531
-
532 505
 /* ----------------------------HELPER FUNCTIONS-------------------------------- */
533 506
 
534 507
 
535
-
536
-
537
-
538
-/*
539
-  */
540 508
 int t_update_timers_after_sending_reply( struct retrans_buff *rb )
541 509
 {
542 510
 	struct cell *Trans = rb->my_T;
543 511
 
544 512
 	/* make sure that if we send something final upstream, everything else
545 513
 	   will be cancelled */
546
-	if (Trans->status>=300 && Trans->inbound_request->REQ_METHOD==METHOD_INVITE )
514
+	if (Trans->status>=300&&Trans->inbound_request->REQ_METHOD==METHOD_INVITE)
547 515
 	{
548 516
 		rb->retr_list = RT_T1_TO_1;
549 517
 		set_timer( hash_table, &(rb->retr_timer), RT_T1_TO_1 );
... ...
@@ -568,10 +536,10 @@ int t_update_timers_after_sending_reply( struct retrans_buff *rb )
568 536
 
569 537
 /* Checks if the new reply (with new_code status) should be sent or not
570 538
  *  based on the current
571
-  * transactin status.
572
-  * Returns 	- branch number (0,1,...) which should be relayed
573
-		- -1 if nothing to be relayed
574
-  */
539
+ * transactin status.
540
+ * Returns 	- branch number (0,1,...) which should be relayed
541
+ *         -1 if nothing to be relayed
542
+ */
575 543
 int t_should_relay_response( struct cell *Trans , int new_code, 
576 544
 	int branch , int *should_store )
577 545
 {
... ...
@@ -619,13 +587,12 @@ int t_should_relay_response( struct cell *Trans , int new_code,
619 587
 					Trans->inbound_response[b]->REPLY_STATUS<200 )
620 588
 					return -1;
621 589
 				if ( Trans->inbound_response[b]->REPLY_STATUS<lowest_s )
622
-      				{
623
-         				lowest_b =b;
624
-         				lowest_s = T->inbound_response[b]->REPLY_STATUS;
625
-      				}
590
+				{
591
+					lowest_b =b;
592
+					lowest_s = T->inbound_response[b]->REPLY_STATUS;
593
+				}
626 594
 			}
627 595
 			return lowest_b;
628
-
629 596
 		/* 1xx except 100 and 2xx will be relayed */
630 597
 		} else if (new_code>100) {
631 598
 			*should_store=1;
... ...
@@ -633,7 +600,7 @@ int t_should_relay_response( struct cell *Trans , int new_code,
633 600
 		}
634 601
 		/* 100 won't be relayed */
635 602
 		else {
636
-			if (!T->inbound_response[branch]) *should_store=1; 
603
+			if (!T->inbound_response[branch]) *should_store=1;
637 604
 			else *should_store=0;
638 605
 			return -1;
639 606
 		}
... ...
@@ -860,7 +827,7 @@ error:
860 827
 
861 828
 
862 829
 /* Builds a CANCEL request based on an INVITE request. CANCEL is send
863
- * to same address */
830
+ * to same address as the INVITE */
864 831
 int t_build_and_send_CANCEL(struct cell *Trans,unsigned int branch)
865 832
 {
866 833
 	struct sip_msg      *p_msg;
... ...
@@ -870,6 +837,13 @@ int t_build_and_send_CANCEL(struct cell *Trans,unsigned int branch)
870 837
 	int                  n;
871 838
 	struct retrans_buff *srb;
872 839
 
840
+	if (Trans->outbound_cancel[branch]!=NO_CANCEL)
841
+	{
842
+		DBG("DEBUG: t_build_and_send_CANCEL: this branch was already canceled"
843
+			" : dropping local cancel! \n");
844
+		return 1;
845
+	}
846
+	
873 847
 	cancel_buf = 0;
874 848
 	via = 0;
875 849
 	p_msg = Trans->inbound_request;
... ...
@@ -956,9 +930,30 @@ int t_build_and_send_CANCEL(struct cell *Trans,unsigned int branch)
956 930
 	/* end of message */
957 931
 	append_mem_block(p,CRLF,CRLF_LEN);
958 932
 	*p=0;
959
-	
960 933
 
961
-	DBG("LOCAL CANCEL = \n%s\n",cancel_buf);
934
+	memset( srb, 0, sizeof( struct retrans_buff ) );
935
+	memcpy( & srb->to, & Trans->outbound_request[branch]->to,
936
+		sizeof (struct sockaddr_in));
937
+	srb->tolen = sizeof (struct sockaddr_in);
938
+	srb->my_T = Trans;
939
+	srb->branch = branch;
940
+	srb->status = STATUS_LOCAL_CANCEL;
941
+	srb->retr_buffer = (char *) srb + sizeof( struct retrans_buff );
942
+	srb->bufflen = len;
943
+	if (Trans->outbound_cancel[branch]) {
944
+		shm_free( srb );	
945
+		LOG(L_WARN, "send_cancel: Warning: CANCEL already sent out\n");
946
+		goto error;
947
+	}
948
+	Trans->outbound_cancel[branch] = srb;
949
+	/*sets and starts the FINAL RESPONSE timer */
950
+	set_timer( hash_table, &(srb->fr_timer), FR_TIMER_LIST );
951
+
952
+	/* sets and starts the RETRANS timer */
953
+	srb->retr_list = RT_T1_TO_1;
954
+	set_timer( hash_table, &(srb->retr_timer), RT_T1_TO_1 );
955
+	DBG("DEBUG: T_build_and_send_CANCEL : sending cancel...\n");
956
+	SEND_BUFFER( srb );
962 957
 
963 958
 	pkg_free(via);
964 959
 	return 1;
... ...
@@ -1131,13 +1126,8 @@ void retransmission_handler( void *attr)
1131 1126
 
1132 1127
 	/* retransmision */
1133 1128
 	DBG("DEBUG: retransmission_handler : resending (t=%p)\n", r_buf->my_T);
1134
-	if (r_buf->reply) {
1129
+	if (r_buf->status!=STATUS_LOCAL_CANCEL && r_buf->status!=STATUS_REQUEST){
1135 1130
 		T=r_buf->my_T;
1136
-/*
1137
-		LOCK_REPLIES( r_buf->my_T );
1138
-		SEND_BUFFER( r_buf );
1139
-		UNLOCK_REPLIES( r_buf->my_T );
1140
-*/
1141 1131
 		t_retransmit_reply();
1142 1132
 	}else{
1143 1133
 		SEND_BUFFER( r_buf );
... ...
@@ -1168,13 +1158,20 @@ void final_response_handler( void *attr)
1168 1158
 #endif
1169 1159
 
1170 1160
 	/* the transaction is already removed from FR_LIST by the timer */
1161
+	if (r_buf->status==STATUS_LOCAL_CANCEL)
1162
+	{
1163
+		DBG("DEBUG: final_response_handler: stop retransmission for"
1164
+			"Local Cancel\n");
1165
+		reset_timer( hash_table , &(r_buf->retr_timer) );
1166
+		return;
1167
+	}
1171 1168
 	/* send a 408 */
1172 1169
 	if ( r_buf->my_T->status<200)
1173 1170
 	{
1174 1171
 		DBG("DEBUG: final_response_handler:stop retransmission and"
1175 1172
 			" send 408 (t=%p)\n", r_buf->my_T);
1176 1173
 		reset_timer( hash_table, &(r_buf->retr_timer) );
1177
-		t_build_and_send_CANCEL( r_buf->my_T ,0);
1174
+		//t_build_and_send_CANCEL( r_buf->my_T ,r_buf->branch);
1178 1175
 		/* dirty hack:t_send_reply would increase ref_count which would indeed
1179 1176
 		result in refcount++ which would not -- until timer processe's
1180 1177
 		T changes again; currently only on next call to t_send_reply from
... ...
@@ -157,7 +157,7 @@ int  t_add_transaction( struct sip_msg* p_msg  );
157 157
  *      -1 - transaction wasn't found
158 158
  *       1 - transaction found
159 159
  */
160
-int t_check( struct sip_msg* , int *branch );
160
+int t_check( struct sip_msg* , int *branch , int* is_cancel);
161 161
 
162 162
 
163 163
 
... ...
@@ -167,7 +167,7 @@ int t_check( struct sip_msg* , int *branch );
167 167
  *      -1 - error during forward
168 168
  */
169 169
 int t_forward( struct sip_msg* p_msg , unsigned int dst_ip ,
170
-				unsigned int dst_port);
170
+										unsigned int dst_port);
171 171
 
172 172
 
173 173
 
... ...
@@ -249,7 +249,7 @@ int t_forward_ack( struct sip_msg* p_msg , unsigned int dest_ip_param ,
249 249
 
250 250
 
251 251
 struct cell* t_lookupOriginalT(  struct s_table* hash_table , struct sip_msg* p_msg );
252
-int t_reply_matching( struct sip_msg* , unsigned int*  );
252
+int t_reply_matching( struct sip_msg* , unsigned int* , unsigned int* );
253 253
 int t_store_incoming_reply( struct cell* , unsigned int , struct sip_msg* );
254 254
 int  t_lookup_request( struct sip_msg* p_msg , int leave_new_locked );
255 255
 int t_all_final( struct cell * );
... ...
@@ -284,6 +284,7 @@ inline int static send_ack( struct cell *t, int branch,
284 284
 	memcpy( & srb->to, & t->ack_to, sizeof (struct sockaddr_in));
285 285
 	srb->tolen = sizeof (struct sockaddr_in);
286 286
 	srb->my_T = t;
287
+	srb->branch = branch;
287 288
 	srb->retr_buffer = (char *) srb + sizeof( struct retrans_buff );
288 289
 	srb->bufflen = len;
289 290
 	LOCK_ACK( t );
... ...
@@ -182,68 +182,70 @@ found:
182 182
  *       0 - transaction wasn't found
183 183
  *       T - transaction found
184 184
  */
185
-struct cell* t_lookupOriginalT(  struct s_table* hash_table , struct sip_msg* p_msg )
185
+struct cell* t_lookupOriginalT(  struct s_table* hash_table ,
186
+													struct sip_msg* p_msg )
186 187
 {
187
-   struct cell         *p_cell;
188
-   struct cell         *tmp_cell;
189
-   unsigned int       hash_index=0;
190
-   struct sip_msg	*t_msg;
188
+	struct cell     *p_cell;
189
+	struct cell     *tmp_cell;
190
+	unsigned int     hash_index=0;
191
+	struct sip_msg  *t_msg;
191 192
 
192
-   /* it's a CANCEL request for sure */
193 193
 
194
-   /* start searching into the table */
195
-   /* hash_index = hash( p_msg->callid->body , get_cseq(p_msg)->number  ) ; */
194
+	/* start searching into the table */
196 195
 	hash_index = p_msg->hash_index;
197
-   DBG("DEBUG: t_lookupOriginalT: searching on hash entry %d\n",hash_index );
198
-
199
-   /* all the transactions from the entry are compared */
200
-   p_cell     = hash_table->entrys[hash_index].first_cell;
201
-   tmp_cell = 0;
202
-   while( p_cell )
203
-   {
204
-     t_msg = p_cell->inbound_request;
205
-
206
-      /* is it the wanted transaction ? */
207
-      /* first only the length are checked */
208
-      if ( p_cell->inbound_request->REQ_METHOD!=METHOD_CANCEL )
209
-         if ( /*callid length*/ EQ_LEN(callid)  )
210
-            if ( get_cseq(t_msg)->number.len==get_cseq(p_msg)->number.len )
211
-               if ( EQ_REQ_URI_LEN )
212
-                   if ( EQ_VIA_LEN(via1) )
213
-                      if ( EQ_LEN(from) && EQ_LEN(to) )
214
-                        //if ( /*tag length*/ (!p_cell->inbound_request->tag && !p_msg->tag) || (p_cell->inbound_request->tag && p_msg->tag && p_cell->inbound_request->tag->body.len == p_msg->tag->body.len) )
215
-                           /* so far the lengths are the same -> let's check the contents */
216
-                            if ( /*callid*/ EQ_STR(callid) )
217
-                               if ( /*cseq_nr*/ !memcmp( get_cseq(t_msg)->number.s , get_cseq(p_msg)->number.s , get_cseq(p_msg)->number.len ) )
218
-                                  if ( EQ_REQ_URI_STR )
219
-                                     if ( EQ_VIA_STR(via1) )
220
-                                        if ( EQ_STR(from) )
221
-                                            //if ( /*tag*/ (!p_cell->inbound_request->tag && !p_msg->tag) || (p_cell->inbound_request->tag && p_msg->tag && memcmp( p_cell->inbound_request->tag->body.s , p_msg->tag->body.s , p_msg->tag->body.len )==0) )
222
-                                              { /* WE FOUND THE GOLDEN EGG !!!! */
223
-                                                DBG("DEBUG: t_lookupOriginalT: canceled transaction found (%x)! \n",p_cell );
224
-                                                return p_cell;
225
-                                             }
226
-      /* next transaction */
227
-      tmp_cell = p_cell;
228
-      p_cell = p_cell->next_cell;
229
-   }
230
-
231
-   /* no transaction found */
232
-   DBG("DEBUG: t_lookupOriginalT: no CANCEL maching found! \n" );
233
-   return 0;
196
+	DBG("DEBUG: t_lookupOriginalT: searching on hash entry %d\n",hash_index );
197
+
198
+	/* all the transactions from the entry are compared */
199
+	p_cell   = hash_table->entrys[hash_index].first_cell;
200
+	tmp_cell = 0;
201
+	while( p_cell )
202
+	{
203
+		t_msg = p_cell->inbound_request;
204
+
205
+		/* is it the wanted transaction ? */
206
+		/* first only the length are checked */
207
+		if ( p_cell->inbound_request->REQ_METHOD!=METHOD_CANCEL
208
+			&& /*callid length*/ EQ_LEN(callid)
209
+			&& get_cseq(t_msg)->number.len==get_cseq(p_msg)->number.len
210
+			&& EQ_REQ_URI_LEN
211
+			&& EQ_VIA_LEN(via1) 
212
+			&& EQ_LEN(from)
213
+			&& EQ_LEN(to) )
214
+				/* so far the lengths are the same
215
+				 let's check the contents */
216
+				if ( /*callid*/ EQ_STR(callid)
217
+					&& /*cseq_nr*/ !memcmp(get_cseq(t_msg)->number.s,
218
+						get_cseq(p_msg)->number.s,get_cseq(p_msg)->number.len)
219
+					&& EQ_REQ_URI_STR
220
+					&& EQ_VIA_STR(via1)
221
+					&& EQ_STR(from) )
222
+					{ /* WE FOUND THE GOLDEN EGG !!!! */
223
+						DBG("DEBUG: t_lookupOriginalT: canceled transaction"
224
+							" found (%x)! \n",p_cell );
225
+						return p_cell;
226
+					}
227
+		/* next transaction */
228
+		tmp_cell = p_cell;
229
+		p_cell = p_cell->next_cell;
230
+	}
231
+
232
+	/* no transaction found */
233
+	DBG("DEBUG: t_lookupOriginalT: no CANCEL maching found! \n" );
234
+	return 0;
234 235
 }
235 236
 
236 237
 
237 238
 
238 239
 
239 240
 /* Returns 0 - nothing found
240
-  *              1  - T found
241
-  */
242
-int t_reply_matching( struct sip_msg *p_msg , unsigned int *p_branch )
241
+ *         1  - T found
242
+ */
243
+int t_reply_matching( struct sip_msg *p_msg , unsigned int *p_branch ,
244
+												unsigned int *local_cancel)
243 245
 {
244 246
 	struct cell*  p_cell;
245 247
 	unsigned int loop_code    = 0;
246
-	unsigned int hash_index = 0;
248
+	unsigned int hash_index   = 0;
247 249
 	unsigned int entry_label  = 0;
248 250
 	unsigned int branch_id    = 0;
249 251
 	char  *loopi,*hashi, *syni, *branchi, *p, *n;
... ...
@@ -251,9 +253,9 @@ int t_reply_matching( struct sip_msg *p_msg , unsigned int *p_branch )
251 253
 	int scan_space;
252 254
 
253 255
 	/* split the branch into pieces: loop_detection_check(ignored),
254
-	     hash_table_id, synonym_id, branch_id*/
256
+	 hash_table_id, synonym_id, branch_id */
255 257
 
256
-	if (!( p_msg->via1 && p_msg->via1->branch && p_msg->via1->branch->value.s) )
258
+	if (!(p_msg->via1 && p_msg->via1->branch && p_msg->via1->branch->value.s))
257 259
 		goto nomatch2;
258 260
 
259 261
 	p=p_msg->via1->branch->value.s;
... ...
@@ -294,35 +296,40 @@ int t_reply_matching( struct sip_msg *p_msg , unsigned int *p_branch )
294 296
 	branchi=p;
295 297
 
296 298
 	/* sanity check */
297
-	if ( (hash_index=reverse_hex2int(hashi, hashl))<0 || hash_index >=TABLE_ENTRIES
298
-	  || (branch_id=reverse_hex2int(branchi, branchl))<0 || branch_id>=MAX_FORK
299
+	if ((hash_index=reverse_hex2int(hashi, hashl))<0||hash_index>=TABLE_ENTRIES
300
+		|| (branch_id=reverse_hex2int(branchi, branchl))<0||branch_id>=MAX_FORK
299 301
 #ifdef USE_SYNONIM
300
-	  || (entry_label=reverse_hex2int(syni, synl))<0
302
+		|| (entry_label=reverse_hex2int(syni, synl))<0
301 303
 #else
302
-	  || loopl!=32
304
+		|| loopl!=32
303 305
 #endif
304
-	   ) {
305
-		DBG("DEBUG: t_reply_matching: poor reply lables %d label %d branch %d\n",
306
-			hash_index, entry_label, branch_id );
306
+	) {
307
+		DBG("DEBUG: t_reply_matching: poor reply lables %d label %d "
308
+			"branch %d\n",hash_index, entry_label, branch_id );
307 309
 		goto nomatch2;
308 310
 	}
309 311
 
310 312
 
311 313
 	DBG("DEBUG: t_reply_matching: hash %d label %d branch %d\n",
312
-	   hash_index, entry_label, branch_id );
314
+		hash_index, entry_label, branch_id );
313 315
 
314 316
 	/* lock the hole entry*/
315 317
 	lock(&(hash_table->entrys[hash_index].mutex));
316 318
 
317
-	/*all the cells from the entry are scan to detect an entry_label matching */
318
-	p_cell     = hash_table->entrys[hash_index].first_cell;
319
+	/*all the cells from the entry are scan to detect an entry_label matching*/
320
+	p_cell = hash_table->entrys[hash_index].first_cell;
319 321
 	while( p_cell )
320 322
 	{
321 323
 		/* is it the cell with the wanted entry_label? */
322 324
 		if ( (get_cseq(p_msg)->method.len ==
323
-		  get_cseq(p_cell->inbound_request)->method.len)
324
-		&& (get_cseq(p_msg)->method.s[0] ==
325
-		  get_cseq(p_cell->inbound_request)->method.s[0])
325
+		get_cseq(p_cell->inbound_request)->method.len)
326
+		&& ((get_cseq(p_msg)->method.s[0] ==
327
+		get_cseq(p_cell->inbound_request)->method.s[0] && (*local_cancel=0)==0)
328
+		|| (get_cseq(p_cell->inbound_request)->method.s[0]=='I' &&
329
+		get_cseq(p_msg)->method.s[0]=='C' 
330
+		&& p_cell->outbound_cancel[branch_id]!=NO_CANCEL
331
+		&& p_cell->outbound_cancel[branch_id]!=EXTERNAL_CANCEL
332
+		&& (*local_cancel=1)==1))
326 333
 #ifdef USE_SYNONIM
327 334
 		&& (p_cell->label == entry_label )
328 335
 #else
... ...
@@ -330,7 +337,7 @@ int t_reply_matching( struct sip_msg *p_msg , unsigned int *p_branch )
330 337
 		  !memcmp(p_cell->inbound_request->add_to_branch_s,loopi,32))
331 338
 #endif
332 339
 		)
333
-			/* has the transaction the wantedbranch? */
340
+			/* has the transaction the wanted branch? */
334 341
 			if ( p_cell->nr_of_outgoings>branch_id &&
335 342
 			p_cell->outbound_request[branch_id] )
336 343
  			{/* WE FOUND THE GOLDEN EGG !!!! */
... ...
@@ -339,7 +346,7 @@ int t_reply_matching( struct sip_msg *p_msg , unsigned int *p_branch )
339 346
 				T_REF( T );
340 347
 				unlock(&(hash_table->entrys[hash_index].mutex));
341 348
 				DBG("DEBUG:XXXXXXXXXXXXXXXXXXXXX t_reply_matching:"
342
-				  " reply matched (T=%p,ref=%x)!\n",T,T->ref_bitmap);
349
+					" reply matched (T=%p,ref=%x)!\n",T,T->ref_bitmap);
343 350
 				return 1;
344 351
 			}
345 352
 		/* next cell */
... ...
@@ -365,9 +372,10 @@ nomatch2:
365 372
   * for current message exists;
366 373
   * it returns 1 if found, 0 if not found, -1 on error
367 374
   */
368
-int t_check( struct sip_msg* p_msg , int *param_branch)
375
+int t_check( struct sip_msg* p_msg , int *param_branch, int *param_cancel)
369 376
 {
370 377
 	int local_branch;
378
+	int local_cancel;
371 379
 
372 380
 	/* is T still up-to-date ? */
373 381
 	DBG("DEBUG: t_check : msg id=%d , global msg id=%d , T on entrance=%p\n", 
... ...
@@ -378,24 +386,26 @@ int t_check( struct sip_msg* p_msg , int *param_branch)
378 386
 		T = T_UNDEFINED;
379 387
 		/* transaction lookup */
380 388
 		if ( p_msg->first_line.type==SIP_REQUEST ) {
381
-
382 389
 			/* force parsing all the needed headers*/
383 390
 			if (parse_headers(p_msg, HDR_EOH )==-1)
384 391
 				return -1;
385
-		t_lookup_request( p_msg , 0 /* unlock before returning */ );
386
-	 	} else {
387
-		 	if ( parse_headers(p_msg, HDR_VIA1|HDR_VIA2|HDR_TO|HDR_CSEQ )==-1 ||
388
-			!p_msg->via1 || !p_msg->via2 || !p_msg->to || !p_msg->cseq )
392
+			t_lookup_request( p_msg , 0 /* unlock before returning */ );
393
+		} else {
394
+			if ( parse_headers(p_msg, HDR_VIA1|HDR_VIA2|HDR_TO|HDR_CSEQ )==-1
395
+			|| !p_msg->via1 || !p_msg->via2 || !p_msg->to || !p_msg->cseq )
389 396
 				return -1;
390
-			t_reply_matching( p_msg , ((param_branch!=0)?(param_branch):(&local_branch)) );
397
+			t_reply_matching( p_msg ,
398
+				((param_branch!=0)?(param_branch):(&local_branch)),
399
+				((param_cancel!=0)?(param_cancel):(&local_cancel)));
400
+
391 401
 		}
392
-#		ifdef EXTRA_DEBUG
402
+#ifdef EXTRA_DEBUG
393 403
 		if ( T && T!=T_UNDEFINED && T->damocles) {
394 404
 			LOG( L_ERR, "ERROR: transaction %p scheduled for deletion "
395 405
 				"and called from t_check\n", T);
396 406
 			abort();
397 407
 		}
398
-#		endif
408
+#endif
399 409
 		DBG("DEBUG: t_check : msg id=%d , global msg id=%d , T on finish=%p\n",
400 410
 			p_msg->id,global_msg_id,T);
401 411
 	} else {
... ...
@@ -21,6 +21,7 @@
21 21
 int t_on_reply_received( struct sip_msg  *p_msg )
22 22
 {
23 23
 	unsigned int  branch,len, msg_status, msg_class, save_clone;
24
+	unsigned int local_cancel;
24 25
 	struct sip_msg *clone, *backup;
25 26
 	int relay;
26 27
 	int start_fr;
... ...
@@ -29,11 +30,23 @@ int t_on_reply_received( struct sip_msg  *p_msg )
29 30
 
30 31
 
31 32
 	/* make sure we know the assosociated tranaction ... */
32
-	if (t_check( p_msg  , &branch )==-1) return 1;
33
+	if (t_check( p_msg  , &branch , &local_cancel)==-1) return 1;
33 34
 	/* ... if there is no such, tell the core router to forward statelessly */
34 35
 	if ( T<=0 ) return 1;
35 36
 
36
-	DBG("DEBUG: t_on_reply_received: Original status =%d\n",T->status);
37
+	DBG("DEBUG: t_on_reply_received: Original status=%d (%d,%d)\n",
38
+		T->status,branch,local_cancel);
39
+
40
+	/* special cases (local cancel reply and another 100 reply!)*/
41
+	if (p_msg->REPLY_STATUS==100 && T->status==100)
42
+		return 0;
43
+	if (local_cancel==1)
44
+	{
45
+		reset_timer( hash_table, &(T_>outbound_cancel[branch]->retr_timer));
46
+		if ( p_msg->REPLY_STATUS>=200 )
47
+			reset_timer( hash_table, &(T_>outbound_cancel[branch]->fr_timer));
48
+		return 0;
49
+	}
37 50
 
38 51
 	/* it can take quite long -- better do it now than later 
39 52
 	   inside a reply_lock */
... ...
@@ -86,16 +99,19 @@ int t_on_reply_received( struct sip_msg  *p_msg )
86 99
 		if ( T->outbound_ack[branch] )
87 100
 		{   /*retransmit*/
88 101
 			SEND_BUFFER( T->outbound_ack[branch] );
89
-		} else if (msg_class>2 ) {   /*on a non-200 reply to INVITE*/
90
-           		DBG("DEBUG: t_on_reply_received: >=3xx reply to INVITE: send ACK\n");
91
-           		if ( t_build_and_send_ACK( T , branch , p_msg )==-1)
92
-           		{
93
-               		LOG( L_ERR , "ERROR: t_on_reply_received: unable to send ACK\n" );
94
-					/* restart FR */
95
-					start_fr=1;
96
-           		}
97
-       		}
98
-   	}
102
+		}else if (msg_class>2 ) {   
103
+			/*on a non-200 reply to INVITE*/
104
+			DBG("DEBUG: t_on_reply_received: >=3xx reply to INVITE:"
105
+				" send ACK\n");
106
+			if ( t_build_and_send_ACK( T , branch , p_msg )==-1)
107
+			{
108
+				LOG( L_ERR , "ERROR: t_on_reply_received:"
109
+					" unable to send ACK\n" );
110
+				/* restart FR */
111
+				start_fr=1;
112
+			}
113
+		}
114
+	}
99 115
 cleanup:
100 116
 	UNLOCK_REPLIES( T );
101 117
 	if (backup) sip_msg_free(backup);
... ...
@@ -119,12 +135,10 @@ error:
119 135
 
120 136
 
121 137
 /* Retransmits the last sent inbound reply.
122
-
123
-  * input: p_msg==request for which I want to retransmit an associated
124
-    reply
125
-  * Returns  -1 -error
126
-  *                1 - OK
127
-  */
138
+ * input: p_msg==request for which I want to retransmit an associated reply
139
+ * Returns  -1 - error
140
+ *           1 - OK
141
+ */
128 142
 int t_retransmit_reply( /* struct sip_msg* p_msg    */ )
129 143
 {
130 144
 
... ...
@@ -152,6 +166,10 @@ int t_retransmit_reply( /* struct sip_msg* p_msg    */ )
152 166
 	return 1;
153 167
 }
154 168
 
169
+
170
+
171
+
172
+
155 173
 /* Force a new response into inbound response buffer.
156 174
   * returns 1 if everything was OK or -1 for erro
157 175
   */
... ...
@@ -161,8 +179,6 @@ int t_send_reply(  struct sip_msg* p_msg , unsigned int code , char * text )
161 179
 	char * buf, *shbuf;
162 180
 	struct retrans_buff *rb;
163 181
 
164
-	DBG("DEBUG: t_send_reply: entered\n");
165
-
166 182
 	buf = build_res_buf_from_sip_req(code,text,0,0,T->inbound_request,&len);
167 183
 	DBG("DEBUG: t_send_reply: buffer computed\n");
168 184
 	if (!buf)
... ...
@@ -191,10 +207,9 @@ int t_send_reply(  struct sip_msg* p_msg , unsigned int code , char * text )
191 207
 		rb->fr_timer.payload = rb;
192 208
 		rb->to.sin_family = AF_INET;
193 209
 		rb->my_T = T;
194
-		rb->reply = code;
210
+		rb->status = code;
195 211
 	}
196 212
 
197
-
198 213
 	/* if this is a first reply (?100), longer replies will probably follow;
199 214
 	   try avoiding shm_resize by higher buffer size */
200 215
 	buf_len = rb->retr_buffer ? len : len + REPLY_OVERBUFFER_LEN;
... ...
@@ -272,7 +287,7 @@ static int push_reply_from_uac_to_uas( struct cell* trans , unsigned int branch
272 287
 		rb->fr_timer.payload =  rb;
273 288
 		rb->to.sin_family = AF_INET;
274 289
 		rb->my_T = trans;
275
-		rb->reply = trans->inbound_response[branch]->REPLY_STATUS;
290
+		rb->status = trans->inbound_response[branch]->REPLY_STATUS;
276 291
 
277 292
 	} else {
278 293
 #ifndef SRL
... ...
@@ -360,7 +375,7 @@ static int push_reply( struct cell* trans , unsigned int branch ,
360 375
 		rb->fr_timer.payload =  rb;
361 376
 		rb->to.sin_family = AF_INET;
362 377
 		rb->my_T = trans;
363
-		rb->reply = trans->inbound_response[branch]->REPLY_STATUS;
378
+		rb->status = trans->inbound_response[branch]->REPLY_STATUS;
364 379
 	};
365 380
 
366 381
 	/* if this is a first reply (?100), longer replies will probably follow;
... ...
@@ -401,7 +416,8 @@ error:
401 416
   */
402 417
 int t_on_reply( struct sip_msg  *p_msg )
403 418
 {
404
-	unsigned int  branch,len, msg_status, msg_class, save_clone;
419
+	unsigned int branch,len, msg_status, msg_class, save_clone;
420
+	unsigned int local_cancel;
405 421
 	struct sip_msg *clone, *backup;
406 422
 	int relay;
407 423
 	int start_fr;
... ...
@@ -412,11 +428,23 @@ int t_on_reply( struct sip_msg  *p_msg )
412 428
 
413 429
 
414 430
 	/* make sure we know the assosociated tranaction ... */
415
-	if (t_check( p_msg  , &branch )==-1) return 1;
431
+	if (t_check( p_msg  , &branch , &local_cancel)==-1) return 1;
416 432
 	/* ... if there is no such, tell the core router to forward statelessly */
417 433
 	if ( T<=0 ) return 1;
418 434
 
419
-	DBG("DEBUG: t_on_reply_received: Original status =%d\n",T->status);
435
+	DBG("DEBUG: t_on_reply_received: Original status=%d (%d,%d)\n",
436
+		T->status,branch,local_cancel);
437
+
438
+	/* special cases (local cancel reply and another 100 reply!)*/
439
+	if (p_msg->REPLY_STATUS==100 && T->status==100)
440
+		return 0;
441
+	if (local_cancel==1)
442
+	{
443
+		reset_timer( hash_table, &(T->outbound_cancel[branch]->retr_timer));
444
+		if ( p_msg->REPLY_STATUS>=200 )
445
+			reset_timer( hash_table, &(T->outbound_cancel[branch]->fr_timer));
446
+		return 0;
447
+	}
420 448
 
421 449
 	/* it can take quite long -- better do it now than later 
422 450
 	   inside a reply_lock */
... ...
@@ -427,12 +455,11 @@ int t_on_reply( struct sip_msg  *p_msg )
427 455
 	msg_class=REPLY_CLASS(p_msg);
428 456
 	is_invite= T->inbound_request->REQ_METHOD==METHOD_INVITE;
429 457
 
430
-    /*  generate the retrans buffer, make a simplified
431
-	    assumption everything but 100 will be fwd-ed;
432
-		sometimes it will result in useless CPU cycles
433
-		but mostly the assumption holds and allows the
434
-		work to be done out of criticial lock region
435
-	 */
458
+	/*  generate the retrans buffer, make a simplified
459
+	assumption everything but 100 will be fwd-ed;
460
+	sometimes it will result in useless CPU cycles
461
+	but mostly the assumption holds and allows the
462
+	work to be done out of criticial lock region */
436 463
 	if (msg_status==100) buf=0;
437 464
 	else {
438 465
 		buf = build_res_buf_from_sip_res ( p_msg, &buf_len);
... ...
@@ -486,16 +513,19 @@ int t_on_reply( struct sip_msg  *p_msg )
486 513
 		if ( T->outbound_ack[branch] )
487 514
 		{   /*retransmit*/
488 515
 			SEND_BUFFER( T->outbound_ack[branch] );
489
-		} else if (msg_class>2 ) {   /*on a non-200 reply to INVITE*/
490
-           		DBG("DEBUG: t_on_reply_received: >=3xx reply to INVITE: send ACK\n");
491
-           		if ( t_build_and_send_ACK( T , branch , p_msg )==-1)
492
-           		{
493
-               		LOG( L_ERR , "ERROR: t_on_reply_received: unable to send ACK\n" );
494
-					/* restart FR */
495
-					start_fr=1;
496
-           		}
497
-       		}
498
-   	}
516
+		} else if (msg_class>2 ) {   
517
+			/*on a non-200 reply to INVITE*/
518
+			DBG("DEBUG: t_on_reply_received: >=3xx reply to INVITE:"
519
+				" send ACK\n");
520
+			if ( t_build_and_send_ACK( T , branch , p_msg )==-1)
521
+			{
522
+				LOG( L_ERR , "ERROR: t_on_reply_received:"
523
+					" unable to send ACK\n" );
524
+				/* restart FR */
525
+				start_fr=1;
526
+			}
527
+		}
528
+	}
499 529
 cleanup:
500 530
 	UNLOCK_REPLIES( T );
501 531
 	if (backup) sip_msg_free(backup);
... ...
@@ -174,7 +174,7 @@ void timer_routine(unsigned int ticks , void * attr)
174 174
 			/* reset the timer list linkage */
175 175
 			tmp_tl = tl->next_tl;
176 176
 			tl->next_tl = tl->prev_tl =0 ; 
177
-			DBG("DEBUG: timer routine: timer[%d] , tl=%p next=%p\n",id,tl,tmp_tl);
177
+			DBG("DEBUG: timer routine:timer[%d],tl=%p next=%p\n",id,tl,tmp_tl);
178 178
 			timers[id].timeout_handler( tl->payload );
179 179
 			tl = tmp_tl;
180 180
 		}
... ...
@@ -267,13 +267,13 @@ static int fixup_t_send_reply(void** param, int param_no)
267 267
 
268 268
 static int w_t_check(struct sip_msg* msg, char* str, char* str2)
269 269
 {
270
-	return t_check( msg , 0 ) ? 1 : -1;
270
+	return t_check( msg , 0 , 0 ) ? 1 : -1;
271 271
 }
272 272
 
273 273
 #ifdef _OBSOLETED_TM
274 274
 static int w_t_forward(struct sip_msg* msg, char* str, char* str2)
275 275
 {
276
-	if (t_check( msg , 0 )==-1) return -1;
276
+	if (t_check( msg , 0 , 0 )==-1) return -1;
277 277
 	if (!T) {
278 278
 		DBG("DEBUG: t_forward: no transaction found for request forwarding\n");
279 279
 		return -1;
... ...
@@ -282,7 +282,7 @@ static int w_t_forward(struct sip_msg* msg, char* str, char* str2)
282 282
 }
283 283
 static int w_t_forward_def(struct sip_msg* msg, char* str, char* str2)
284 284
 {
285
-	if (t_check( msg , 0 )==-1) return -1;
285
+	if (t_check( msg , 0 , 0 )==-1) return -1;
286 286
 	if (!T) {
287 287
 		DBG("DEBUG: t_forward: no transaction found for request forwarding\n");
288 288
 		return -1;
... ...
@@ -291,7 +291,7 @@ static int w_t_forward_def(struct sip_msg* msg, char* str, char* str2)
291 291
 }
292 292
 
293 293
 int w_t_forward_uri( struct sip_msg* p_msg, char* foo, char* bar  ) {
294
-	if (t_check( p_msg , 0 )==-1) return -1;
294
+	if (t_check( p_msg , 0 , 0)==-1) return -1;
295 295
 	if (!T) {
296 296
 		DBG("DEBUG: t_forward: no transaction found for request forwarding\n");
297 297
 		return -1;
... ...
@@ -313,7 +313,7 @@ static int w_t_on_request_received_uri(struct sip_msg* msg, char* str, char* str
313 313
 
314 314
 static int w_t_forward_ack(struct sip_msg* msg, char* str, char* str2)
315 315
 {
316
-	if (t_check( msg , 0 )==-1) return -1;
316
+	if (t_check( msg , 0 , 0 )==-1) return -1;
317 317
 	if (!T) {
318 318
 		DBG("DEBUG: t_forward_ack: no transaction found for request forwarding\n");
319 319
 		return -1;
... ...
@@ -322,7 +322,7 @@ static int w_t_forward_ack(struct sip_msg* msg, char* str, char* str2)
322 322
 }
323 323
 static int w_t_forward_nonack(struct sip_msg* msg, char* str, char* str2)
324 324
 {
325
-	if (t_check( msg , 0 )==-1) return -1;
325
+	if (t_check( msg , 0 , 0)==-1) return -1;
326 326
 	if (!T) {
327 327
 		DBG("DEBUG: t_forward_nonack: no transaction found for request forwarding\n");
328 328
 		return -1;
... ...
@@ -334,7 +334,7 @@ static int w_t_forward_nonack(struct sip_msg* msg, char* str, char* str2)
334 334
 
335 335
 static int w_t_send_reply(struct sip_msg* msg, char* str, char* str2)
336 336
 {
337
-	if (t_check( msg , 0 )==-1) return -1;
337
+	if (t_check( msg , 0 , 0)==-1) return -1;
338 338
 	if (!T) {
339 339
 		LOG(L_ERR, "ERROR: t_send_reply: cannot send a t_reply to a message "
340 340
 			"for which no T-state has been established\n");
... ...
@@ -345,7 +345,7 @@ static int w_t_send_reply(struct sip_msg* msg, char* str, char* str2)
345 345
 
346 346
 static int w_t_release(struct sip_msg* msg, char* str, char* str2)
347 347
 {
348
-	if (t_check( msg  , 0 )==-1) return 1;
348
+	if (t_check( msg  , 0 , 0 )==-1) return 1;
349 349
 	if ( T && T!=T_UNDEFINED ) 
350 350
 		return t_put_on_wait( T );
351 351
 	return 1;
... ...
@@ -361,13 +361,13 @@ static int w_t_unref( struct sip_msg* p_msg, char* foo, char* bar )
361 361
 
362 362
 static w_t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar  )
363 363
 {
364
-	if (t_check( p_msg  , 0 )==-1) return 1;
365
-	if (T) return t_retransmit_reply( /* p_msg */ );
364
+	if (t_check( p_msg  , 0 , 0 )==-1) return 1;
365
+	if (T) return t_retransmit_reply( p_msg );
366 366
 	else return -1;
367 367
 }
368 368
 
369 369
 static int w_t_add_transaction( struct sip_msg* p_msg, char* foo, char* bar ) {
370
-	if (t_check( p_msg , 0 )==-1) return -1;
370
+	if (t_check( p_msg , 0 , 0 )==-1) return -1;
371 371
 	if (T) {
372 372
 		LOG(L_ERR,"ERROR: t_add_transaction: won't add a retransmission\n");
373 373
 		return -1;
... ...
@@ -29,7 +29,7 @@ loadmodule "modules/tm/tm.so"
29 29
 #loadmodule "modules/rr/rr.so"
30 30
 loadmodule "modules/maxfwd/maxfwd.so"
31 31
 loadmodule "modules/sl/sl.so"
32
-loadmodule "modules/cpl/cpl.so"
32
+#loadmodule "modules/cpl/cpl.so"
33 33
 
34 34
 
35 35
 route{