Browse code

BUGS of course :))

Bogdan-Andrei Iancu authored on 10/12/2001 21:30:00
Showing 6 changed files
... ...
@@ -44,7 +44,7 @@ ARCH = $(shell uname -s)
44 44
 #		malloc etc.)
45 45
 DEFS= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
46 46
 	 -DDNS_IP_HACK  -DSHM_MEM \
47
-	 -DPKG_MALLOC -DDBG_QM_MALLOC -DNODEBUG
47
+	 -DPKG_MALLOC #-DDBG_QM_MALLOC -DNODEBUG
48 48
 #-DEXTRA_DEBUG
49 49
 # -DUSE_SHM_MEM
50 50
 #-DNO_DEBUG 
... ...
@@ -16,26 +16,29 @@ void free_cell( struct cell* dead_cell )
16 16
    struct retrans_buff* rb;
17 17
    char *b;
18 18
 
19
-
20
-   /* UA Server */ 
19
+   DBG("DEBUG: free_cell: start\n");
20
+   /* UA Server */
21
+   DBG("DEBUG: free_cell: inbound request %p\n",dead_cell->inbound_request);
21 22
    if ( dead_cell->inbound_request )
22 23
       sip_msg_free( dead_cell->inbound_request );
24
+   DBG("DEBUG: free_cell: outbound response %p\n",dead_cell->outbound_response);
23 25
    if ( dead_cell->outbound_response )
24 26
    {
25 27
       b = dead_cell->outbound_response->retr_buffer ;
26 28
       dead_cell->outbound_response->retr_buffer = NULL;
27 29
       sh_free( b );
28 30
 
29
-      rb = dead_cell->outbound_response; 
31
+      rb = dead_cell->outbound_response;
30 32
       dead_cell->outbound_response = NULL;
31 33
       sh_free( rb );
32
-      
34
+
33 35
    }
34 36
 
35 37
   /* UA Clients */
36 38
    for ( i =0 ; i<dead_cell->nr_of_outgoings;  i++ )
37 39
    {
38 40
       /* outbound requests*/
41
+      DBG("DEBUG: free_cell: outbound_request[%d] %p\n",i,dead_cell->outbound_request[i]);
39 42
       if ( dead_cell->outbound_request[i] )
40 43
       {
41 44
 	 b = dead_cell->outbound_request[i]->retr_buffer;
... ...
@@ -47,6 +50,7 @@ void free_cell( struct cell* dead_cell )
47 50
          sh_free( rb );
48 51
       }
49 52
       /* outbound requests*/
53
+      DBG("DEBUG: free_cell: inbound_response[%d] %p\n",i,dead_cell->inbound_response[i]);
50 54
       if ( dead_cell -> inbound_response[i] )
51 55
          sip_msg_free( dead_cell->inbound_response[i] );
52 56
    }
... ...
@@ -54,6 +58,7 @@ void free_cell( struct cell* dead_cell )
54 58
    release_cell_lock( dead_cell );
55 59
    /* the cell's body */
56 60
    sh_free( dead_cell );
61
+   DBG("DEBUG: free_cell: start\n");
57 62
 }
58 63
 
59 64
 
... ...
@@ -170,6 +175,7 @@ struct cell*  build_cell( struct sip_msg* p_msg )
170 175
    /* all pointers from outbound_request array are NULL */
171 176
    /* all pointers from outbound_response array are NULL */
172 177
    /*init the links with the canceled / canceler transaction */
178
+   new_cell->relaied_reply_branch   = -1;
173 179
    new_cell->T_canceled  = T_UNDEFINED;
174 180
    new_cell->T_canceler  = T_UNDEFINED;
175 181
 
... ...
@@ -93,20 +93,19 @@ typedef struct cell
93 93
    struct cell *T_canceled;
94 94
    struct cell *T_canceler;
95 95
 
96
-   /*if the request received an ACK - used only by INVITE*/
97
-   unsigned int isACKed;
98
-
99 96
    /* usefull data */
100 97
    /* UA Server */
101 98
    struct sip_msg         *inbound_request;
102 99
    struct retrans_buff   *outbound_response;
103 100
    unsigned int             status;
104 101
    str*                             tag;
105
-   /* array of outgoing requests and its responses */
102
+   unsigned int             inbound_request_isACKed;
103
+   int                              relaied_reply_branch;
106 104
    int                               nr_of_outgoings;
107 105
    /* UA Clients */
108 106
    struct retrans_buff   *outbound_request[ MAX_FORK ];
109 107
    struct sip_msg          *inbound_response[ MAX_FORK ];
108
+   unsigned int             outbound_request_isACKed[MAX_FORK];
110 109
 }cell_type;
111 110
 
112 111
 
... ...
@@ -6,28 +6,30 @@
6 6
 #include "../../timer.h"
7 7
 
8 8
 #define stop_RETR_and_FR_timers(h_table,p_cell)    \
9
-	do{ int ijk; \
9
+	{ int ijk; \
10
+		DBG("DEBUG:stop_RETR_and_FR_timers : start \n");\
10 11
 		if ( (p_cell)->outbound_response )  {  \
11
-			remove_from_timer_list( \
12
-				(h_table) , \
12
+			remove_from_timer_list( (h_table) , \
13 13
 				(&((p_cell)->outbound_response->tl[RETRASMISSIONS_LIST])), \
14
-				RETRASMISSIONS_LIST\
15
-			); \
14
+				RETRASMISSIONS_LIST ); \
16 15
 			remove_from_timer_list( (h_table), \
17
-					(&((p_cell)->outbound_response->tl[FR_TIMER_LIST])), \
18
-					FR_TIMER_LIST );\
16
+				(&((p_cell)->outbound_response->tl[FR_TIMER_LIST])), \
17
+				FR_TIMER_LIST );\
19 18
 		} \
19
+		DBG("DEBUG:stop_RETR_and_FR_timers : %d \n",(p_cell)->nr_of_outgoings);\
20 20
 		for( ijk=0 ; ijk<(p_cell)->nr_of_outgoings ; ijk++ )  { \
21
-			remove_from_timer_list( \
22
-				(h_table) , \
21
+			DBG("DEBUG:stop_RETR_and_FR_timers : branch[%d] RETR\n",ijk);\
22
+			remove_from_timer_list( (h_table) , \
23 23
 				(&((p_cell)->outbound_request[ijk]->tl[RETRASMISSIONS_LIST])),\
24
-				RETRASMISSIONS_LIST \
25
-			); \
24
+				RETRASMISSIONS_LIST ); \
25
+			DBG("DEBUG:stop_RETR_and_FR_timers : branch[%d] FR\n",ijk);\
26 26
 			remove_from_timer_list( (h_table) , \
27 27
 				(&((p_cell)->outbound_request[ijk]->tl[FR_TIMER_LIST])), \
28 28
 				FR_TIMER_LIST ); \
29
+			DBG("DEBUG:stop_RETR_and_FR_timers : branch]%d] done\n",ijk);\
29 30
 		} \
30
-	}while(0)
31
+		DBG("DEBUG:stop_RETR_and_FR_timers : stop\n");\
32
+	}
31 33
 
32 34
 
33 35
 #define insert_into_timer(hash_table,new_tl,list_id,time_out) \
... ...
@@ -79,9 +81,11 @@ void tm_shutdown()
79 81
     struct timer_link  *tl, *tmp;
80 82
     int i;
81 83
 
84
+    DBG("DEBUG: tm_shutdown : start\n");
82 85
     /*remember the DELETE LIST */
83 86
     tl = hash_table->timers[DELETE_LIST].first_tl;
84 87
 
88
+    DBG("DEBUG: tm_shutdown : empting DELETE list\n");
85 89
     /*unlink the lists*/
86 90
     for( i=NR_OF_TIMER_LISTS ; i>=0 ; i-- )
87 91
     {
... ...
@@ -94,7 +98,10 @@ void tm_shutdown()
94 98
     for(   ;  tl  ;  tmp=tl->next_tl , free_cell((struct cell*)tl->payload) , tl=tmp );
95 99
 
96 100
     /* destroy the hash table */
101
+    DBG("DEBUG: tm_shutdown : empting hash table\n");
97 102
     free_hash_table( hash_table );
103
+
104
+    DBG("DEBUG: tm_shutdown : done\n");
98 105
 }
99 106
 
100 107
 
... ...
@@ -292,7 +299,9 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
292 299
       return 1;
293 300
    }
294 301
 
295
-   /* if it's forwarded for the first time ; else the request is retransmited from the transaction buffer */
302
+   /* if it's forwarded for the first time ; else the request is retransmited from the transaction buffer
303
+     * when forwarding an ACK, this condition will br all the time false because
304
+     * the forwarded INVITE is in the retransmission buffer */
296 305
    if ( T->outbound_request[branch]==NULL )
297 306
    {
298 307
       DBG("DEBUG: t_forward: first time forwarding\n");
... ...
@@ -332,7 +341,8 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
332 341
       /* allocates a new retrans_buff for the outbound request */
333 342
       DBG("DEBUG: t_forward: building outbound request\n");
334 343
       T->outbound_request[branch] = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) );
335
-      if (!T->outbound_request[branch]) {
344
+      if (!T->outbound_request[branch])
345
+      {
336 346
         LOG(L_ERR, "ERROR: t_forward: out of shmem\n");
337 347
 	goto error;
338 348
       }
... ...
@@ -364,9 +374,18 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
364 374
       insert_into_timer( hash_table , (&(T->outbound_request[branch]->tl[RETRASMISSIONS_LIST])), RETRASMISSIONS_LIST , RETR_T1 );
365 375
    }/* end for the first time */
366 376
 
367
-    /* if we are forwarding a CANCEL*/
377
+   /* if we are forwarding an ACK*/
378
+   if (  p_msg->first_line.u.request.method_value==METHOD_ACK &&
379
+   T->relaied_reply_branch>=0 && T->relaied_reply_branch<=T->nr_of_outgoings)
380
+   {
381
+      DBG("DEBUG: t_forward: forwarding ACK [%d]\n",T->relaied_reply_branch);
382
+      t_build_and_send_ACK( T, branch , T->inbound_response[T->relaied_reply_branch] );
383
+      T->inbound_request_isACKed = 1;
384
+     return 1;
385
+   } else /* if we are forwarding a CANCEL*/
368 386
    if (  p_msg->first_line.u.request.method_value==METHOD_CANCEL )
369 387
    {
388
+      DBG("DEBUG: t_forward: forwarding CANCEL\n");
370 389
        /* if no transaction to CANCEL */
371 390
       /* or if the canceled transaction has a final status -> drop the CANCEL*/
372 391
       if ( T->T_canceled==T_NULL || T->T_canceled->status>=200)
... ...
@@ -521,11 +540,23 @@ int t_on_reply_received( struct sip_msg  *p_msg )
521 540
    if ( !T->inbound_response[branch] && p_msg->first_line.u.reply.statusclass==1 && T->inbound_request->first_line.u.request.method_value==METHOD_INVITE )
522 541
       insert_into_timer( hash_table , (&(T->outbound_request[branch]->tl[FR_TIMER_LIST])) , FR_TIMER_LIST , INV_FR_TIME_OUT);
523 542
 
524
-   /* on a non-200 reply to INVITE, generate local ACK */
525
-   if ( T->inbound_request->first_line.u.request.method_value==METHOD_INVITE && p_msg->first_line.u.reply.statusclass>2 )
543
+   /* get response for INVITE */
544
+   if ( T->inbound_request->first_line.u.request.method_value==METHOD_INVITE )
526 545
    {
527
-      DBG("DEBUG: t_on_reply_received: >=3xx reply to INVITE: send ACK\n");
528
-      t_build_and_send_ACK( T , branch , p_msg );
546
+       if ( T->outbound_request_isACKed[branch] )
547
+       {   /*retransmit*/
548
+           udp_send( T->outbound_request[branch]->retr_buffer, T->outbound_request[branch]->bufflen,
549
+             (struct sockaddr*)&(T->outbound_request[branch]->to) , sizeof(struct sockaddr_in) );
550
+       }
551
+       else if (p_msg->first_line.u.reply.statusclass>2 )
552
+       {   /*on a non-200 reply to INVITE*/
553
+           DBG("DEBUG: t_on_reply_received: >=3xx reply to INVITE: send ACK\n");
554
+           if ( t_build_and_send_ACK( T , branch , p_msg )==-1)
555
+           {
556
+               LOG( L_ERR , "ERROR: t_on_reply_received: unable to send ACK\n" );
557
+               return 0;
558
+           }
559
+       }
529 560
    }
530 561
 
531 562
    #ifdef FORKING
... ...
@@ -543,21 +574,20 @@ int t_on_reply_received( struct sip_msg  *p_msg )
543 574
       insert_into_timer( hash_table , (&(T->outbound_request[branch]->tl[RETRASMISSIONS_LIST])) , RETRASMISSIONS_LIST , RETR_T2 );
544 575
    }
545 576
 
546
-   /*store the inbound reply*/
547
-   /* t_store_incoming_reply( T , branch , p_msg ); */
548
-   /* if there is a previous reply, replace it */
577
+   /*store the inbound reply - if there is a previous reply, replace it */
549 578
    if ( T->inbound_response[branch] ) {
550 579
       sip_msg_free( T->inbound_response[branch] ) ;
551
-      DBG("DEBUG: t_store_incoming_reply: sip_msg_free done....\n");
580
+      DBG("DEBUG: t_store_incoming_reply: previous inbound reply freed....\n");
552 581
    }
553 582
    T->inbound_response[branch] = clone;
554
-   T->status = p_msg->first_line.u.reply.statuscode;
555 583
 
556 584
    if ( p_msg->first_line.u.reply.statusclass>=3 && p_msg->first_line.u.reply.statusclass<=5 )
557 585
    {
558
-      if ( t_all_final(T) && relay_lowest_reply_upstream( T , p_msg ) == -1 && clone ) {
559
-	T->inbound_response[branch]=NULL;
586
+      if ( t_all_final(T) && relay_lowest_reply_upstream( T , p_msg )==-1 && clone )
587
+      {
588
+        T->inbound_response[branch]=NULL;
560 589
         sip_msg_free( clone );
590
+       DBG("DEBUG: t_store_incoming_reply: DONE WITH ERROR!! :((((((((((((((((((((((((((((\n");
561 591
         return -1;
562 592
       }
563 593
    }
... ...
@@ -571,7 +601,9 @@ int t_on_reply_received( struct sip_msg  *p_msg )
571 601
    }
572 602
 
573 603
    /* nothing to do for the ser core */
574
-    return 0;
604
+
605
+   DBG("DEBUG: t_store_incoming_reply: DONE WITH SUCCESS!! :)))))))))))))))))))))))\n");
606
+   return 0;
575 607
 }
576 608
 
577 609
 
... ...
@@ -1018,7 +1050,7 @@ int relay_lowest_reply_upstream( struct cell *Trans , struct sip_msg *p_msg )
1018 1050
 
1019 1051
    DBG("DEBUG: relay_lowest_reply_upstream: lowest reply [%d]=%d\n",lowest_i,lowest_v);
1020 1052
 
1021
-   if ( lowest_i != -1 && push_reply_from_uac_to_uas( T ,lowest_i ) != -1 )
1053
+   if ( lowest_i != -1 && push_reply_from_uac_to_uas( T ,lowest_i ) == -1 )
1022 1054
 	return -1;
1023 1055
 
1024 1056
    return lowest_i;
... ...
@@ -1070,7 +1102,7 @@ int push_reply_from_uac_to_uas( struct cell* trans , unsigned int branch )
1070 1102
       }
1071 1103
    }
1072 1104
 
1073
-   /*  */
1105
+   /*  generate the retrans buffer */
1074 1106
    buf = build_res_buf_from_sip_res ( trans->inbound_response[branch], &len);
1075 1107
    if (!buf) {
1076 1108
 	LOG(L_ERR, "ERROR: push_reply_from_uac_to_uas: no shmem for outbound reply buffer\n");
... ...
@@ -1086,12 +1118,17 @@ int push_reply_from_uac_to_uas( struct cell* trans , unsigned int branch )
1086 1118
    memcpy( trans->outbound_response->retr_buffer , buf , len );
1087 1119
    free( buf ) ;
1088 1120
 
1089
-   /* start/stops the proper timers*/
1121
+   /* update the status*/
1122
+   trans->status = trans->inbound_response[branch]->first_line.u.reply.statuscode;
1123
+   if ( trans->inbound_response[branch]->first_line.u.reply.statuscode>=200 &&
1124
+         trans->relaied_reply_branch==-1 )
1125
+       trans->relaied_reply_branch = branch;
1126
+
1127
+    /* start/stops the proper timers*/
1090 1128
    t_update_timers_after_sending_reply( T->outbound_response );
1091 1129
 
1092 1130
    /*send the reply*/
1093 1131
    t_retransmit_reply( trans->inbound_response[branch], 0 , 0 );
1094
-
1095 1132
    return 1;
1096 1133
 }
1097 1134
 
... ...
@@ -1355,6 +1392,7 @@ void retransmission_handler( void *attr)
1355 1392
 
1356 1393
    /* re-insert into RETRASMISSIONS_LIST */
1357 1394
    insert_into_timer( hash_table , (&(r_buf->tl[RETRASMISSIONS_LIST])) , RETRASMISSIONS_LIST , r_buf->timeout_value );
1395
+   DBG("DEBUG: retransmission_handler : done\n");
1358 1396
 }
1359 1397
 
1360 1398
 
... ...
@@ -1378,6 +1416,7 @@ void final_response_handler( void *attr)
1378 1416
       DBG("DEBUG: final_response_handler : cansel transaction->put on wait\n");
1379 1417
       t_put_on_wait(  r_buf->my_T );
1380 1418
    }
1419
+   DBG("DEBUG: final_response_handler : done\n");
1381 1420
 }
1382 1421
 
1383 1422
 
... ...
@@ -1395,6 +1434,7 @@ void wait_handler( void *attr)
1395 1434
    stop_RETR_and_FR_timers(hash_table,p_cell) ;
1396 1435
    /* put it on DEL_LIST - sch for del */
1397 1436
     add_to_tail_of_timer( hash_table, (&(p_cell->dele_tl)), DELETE_LIST, DEL_TIME_OUT );
1437
+   DBG("DEBUG: wait_handler : done\n");
1398 1438
 }
1399 1439
 
1400 1440
 
... ...
@@ -1417,6 +1457,7 @@ void delete_handler( void *attr)
1417 1457
        /* else it's readded to del list for future del */
1418 1458
        add_to_tail_of_timer( hash_table, (&(p_cell->dele_tl)), DELETE_LIST, DEL_TIME_OUT );
1419 1459
     }
1460
+    DBG("DEBUG: delete_handler : done\n");
1420 1461
 }
1421 1462
 
1422 1463
 
... ...
@@ -7,6 +7,20 @@
7 7
 #include "../../dprint.h"
8 8
 
9 9
 
10
+void print_timer_list(struct s_table* hash_table, int list_id)
11
+{
12
+   struct timer* timer_list=&(hash_table->timers[ list_id ]);
13
+   struct timer_link *tl ;
14
+
15
+   tl = timer_list->first_tl;
16
+   while (tl)
17
+   {
18
+      DBG("DEBUG: print_timer_list[%d]: %p, next=%p \n",list_id, tl, tl->next_tl);
19
+      tl = tl->next_tl;
20
+   }
21
+}
22
+
23
+
10 24
 void remove_from_timer_list_dummy( struct s_table* hash_table , struct timer_link* tl , int list_id)
11 25
 {
12 26
    struct timer* timer_list=&(hash_table->timers[ list_id ]);
... ...
@@ -62,6 +76,8 @@ void add_to_tail_of_timer_list( struct s_table* hash_table , struct timer_link*
62 76
        timer_list->first_tl = tl;
63 77
        timer_list->last_tl = tl;
64 78
    }
79
+
80
+   //print_timer_list(hash_table, list_id);
65 81
    /* give the list lock away */
66 82
    unlock( timer_list->mutex );
67 83
 }
... ...
@@ -105,6 +121,7 @@ void insert_into_timer_list( struct s_table* hash_table , struct timer_link* new
105 121
        timer_list->first_tl = new_tl;
106 122
     new_tl->next_tl = tl;
107 123
 
124
+   //print_timer_list(hash_table, list_id);
108 125
    /* give the list lock away */
109 126
     unlock( timer_list->mutex );
110 127
 }
... ...
@@ -127,6 +144,7 @@ void remove_from_timer_list( struct s_table* hash_table , struct timer_link* tl
127 144
       remove_from_timer_list_dummy( hash_table , tl , list_id);
128 145
    }
129 146
 
147
+   //print_timer_list(hash_table, list_id);
130 148
    /* give the list lock away */
131 149
    unlock( timer_list->mutex );
132 150
 }
... ...
@@ -139,8 +157,9 @@ void remove_from_timer_list( struct s_table* hash_table , struct timer_link* tl
139 157
 struct timer_link  *check_and_split_time_list( struct s_table* hash_table, int list_id ,int time)
140 158
 {
141 159
    struct timer* timer_list=&(hash_table->timers[ list_id ]);
142
-   struct timer_link *tl ;
160
+   struct timer_link *tl , *tmp;
143 161
 
162
+   //DBG("DEBUG : check_and_split_time_list: start\n");
144 163
    /* the entire timer list is locked now -- noone else can manipulate it */
145 164
    lock( timer_list->mutex );
146 165
 
... ...
@@ -162,19 +181,24 @@ struct timer_link  *check_and_split_time_list( struct s_table* hash_table, int l
162 181
     {
163 182
       tl = timer_list->first_tl;
164 183
       timer_list->first_tl = timer_list->last_tl = 0;
165
-     goto exit;
184
+      //DBG("DEBUG : check_and_split_time_list: done, EVERY returns %p , list=%p\n",tl,timer_list->first_tl);
185
+      goto exit;
166 186
     }
167 187
 
168 188
     /*I have to split it somewhere in the middle */
169 189
     tl->prev_tl->next_tl=0;
170 190
     tl->prev_tl = 0;
191
+    tmp = timer_list->first_tl;
171 192
     timer_list->first_tl = tl;
172
-    tl = timer_list->first_tl;
193
+    tl = tmp;
194
+   //DBG("DEBUG : check_and_split_time_list: done, SPLIT returns %p , list=%p\n",tl,timer_list->first_tl);
173 195
 
174 196
 exit:
175 197
    /* give the list lock away */
176 198
    unlock( timer_list->mutex );
177 199
 
200
+   //DBG("DEBUG : check_and_split_time_list: done, returns %p\n",tl);
201
+   //print_timer_list(hash_table, list_id);
178 202
    return tl;
179 203
 }
180 204
 
... ...
@@ -198,6 +222,7 @@ void timer_routine(unsigned int ticks , void * attr)
198 222
       {
199 223
          tmp_tl = tl->next_tl;
200 224
          tl->next_tl = tl->prev_tl =0 ;
225
+         DBG("DEBUG: timer routine: timer[%d] , tl=%p next=%p\n",id,tl,tmp_tl);
201 226
          timers[id].timeout_handler( tl->payload );
202 227
          tl = tmp_tl;
203 228
       }
... ...
@@ -24,6 +24,7 @@ route{
24 24
 	if ( t_lookup_request()) {
25 25
 		if ( method=="ACK" )	{
26 26
 			log("SER: ACK received -> t_release\n");
27
+			t_forward("iptel.org", "5060" );
27 28
 			t_release();
28 29
 		} else {
29 30
 			t_retransmit_reply();
... ...
@@ -39,7 +40,7 @@ route{
39 40
 			log("SER: new transaction\n");
40 41
 			t_send_reply("100", "trying -- your call is important to us");
41 42
 		};
42
-		rewritehost("iptel.org");
43
+		#rewritehost("iptel.org");
43 44
 		# XXX ... it wants me to put port nr in ""
44 45
 		#t_forward("benetnash.fokus.gmd.de", "5080" );
45 46
 		#t_forward("iptel.org", "5060" );
... ...
@@ -48,5 +49,5 @@ route{
48 49
 		# t_forward("fox.iptel.org" );
49 50
 		# XXX t_forward_uri ... not done yet
50 51
 	};
51
-		
52
+
52 53
 }