Browse code

*** empty log message ***

Bogdan-Andrei Iancu authored on 26/11/2001 23:11:19
Showing 5 changed files
... ...
@@ -1,34 +1,15 @@
1 1
 #include "h_table.h"
2 2
 
3
-struct cell      *T;
4
-unsigned int  global_msg_id;
5
-struct s_table*  hash_table;
6 3
 
7
-
8
-int t_reply_matching( struct s_table* , struct sip_msg* , struct cell** , unsigned int*  );
9
-int t_store_incoming_reply( struct cell* , unsigned int , struct sip_msg* );
10
-int t_relay_reply( struct cell* , unsigned int , struct sip_msg* );
11
-int t_check( struct s_table* , struct sip_msg*  );
12
-int t_all_final( struct cell * );
13
-int relay_lowest_reply_upstream( struct cell *Trans , struct sip_msg *p_msg );
14
-int push_reply_from_uac_to_uas( struct sip_msg * , unsigned int );
15
-
16
-void del_Transaction( struct s_table *hash_table , struct cell * p_cell );
17
-void remove_from_hash_table( struct s_table *hash_table,  struct cell * p_cell );
18
-void start_FR_timer( struct s_table* hash_table, struct cell* p_cell );
19
-void start_WT_timer( struct s_table* hash_table, struct cell* p_cell );
20
-
21
-
22
-
23
-
24
-void free_cell( struct cell* dead_cell )      // TO DO UPDATE
4
+/*   Frees the all the containes of a cell and the cell's body itself
5
+  */
6
+void free_cell( struct cell* dead_cell )
25 7
 {
26 8
    int i;
27 9
 
28 10
    /* inbound_request */
29
-   sh_free( dead_cell->inbound_request->orig );
30
-   sh_free( dead_cell->inbound_request->buf );
31
-   sh_free( dead_cell->inbound_request );
11
+   if ( dead_cell->inbound_request )
12
+      sip_msg_free( dead_cell->inbound_request );
32 13
    /* inbound_response */
33 14
    if ( dead_cell->inbound_response )
34 15
    {
... ...
@@ -39,23 +20,27 @@ void free_cell( struct cell* dead_cell )      // TO DO UPDATE
39 20
    for ( i =0 ; i<dead_cell->nr_of_outgoings;  i++ )
40 21
    {
41 22
       /* outbound requests*/
42
-      sh_free( dead_cell->outbound_request[i]->buffer );
43
-      sh_free( dead_cell->outbound_request[i] );
44
-      /* outbound requests*/
45
-      if ( dead_cell -> outbound_response[i] )
23
+      if ( dead_cell->outbound_request[i] )
46 24
       {
47
-         sh_free( dead_cell->outbound_response[i]->orig );
48
-         sh_free( dead_cell->outbound_response[i]->buf );
49
-         sh_free( dead_cell->outbound_response[i] );
25
+         sh_free( dead_cell->outbound_request[i]->buffer );
26
+         sh_free( dead_cell->outbound_request[i] );
50 27
       }
28
+      /* outbound requests*/
29
+      if ( dead_cell -> outbound_response[i] )
30
+         sip_msg_free( dead_cell->outbound_response[i] );
51 31
    }
52 32
    /* mutex */
53 33
    release_cell_lock( dead_cell );
34
+   /* the cell's body */
54 35
    sh_free( dead_cell );
55 36
 }
56 37
 
57 38
 
58 39
 
40
+
41
+/* Release all the data contained by the hash table. All the aux. structures
42
+  *  as sems, lists, etc, are also released
43
+  */
59 44
 void free_hash_table( struct s_table *hash_table )
60 45
 {
61 46
    struct cell* p_cell;
... ...
@@ -65,34 +50,25 @@ void free_hash_table( struct s_table *hash_table )
65 50
 
66 51
    if (hash_table)
67 52
    {
68
-      if ( hash_table->entrys )
53
+      /* remove the data contained by each entry */
54
+      for( i = 0 ; i<TABLE_ENTRIES; i++)
69 55
       {
70
-         /* remove the hash table entry by entry */
71
-         for( i = 0 ; i<TABLE_ENTRIES; i++)
56
+         release_entry_lock( (hash_table->entrys)+i );
57
+         /* delete all synonyms at hash-collision-slot i */
58
+         for( p_cell = hash_table->entrys[i].first_cell; p_cell; p_cell = tmp_cell )
72 59
          {
73
-             release_entry_lock( (hash_table->entrys)+i );
74
-             /* delete all synonyms at hash-collision-slot i */
75
-              for( p_cell = hash_table->entrys[i].first_cell; p_cell; p_cell = tmp_cell )
76
-              {
77
-                tmp_cell = p_cell->next_cell;
78
-                free_cell( p_cell );
79
-              }
60
+            tmp_cell = p_cell->next_cell;
61
+            free_cell( p_cell );
80 62
          }
81
-	/* Oooops! Error here */
82
-         sh_free( hash_table->entrys );
83 63
       }
84 64
 
85
-      if (hash_table->timers ) {
86
-       /* for each of the timer lists ... */
87
-         for( i=0; i<NR_OF_TIMER_LISTS ; i++ )
88
-           {
89
-              /* ... delete all cells on the timer list */
90
-            while( (tl=remove_from_timer_list_from_head( hash_table, i ))!=0 )
91
-                  /*free_cell( p_cell ) TO DO!! */ ;
92
-               release_timerlist_lock( &(hash_table->timers[i]) );
93
-         }
94
-         sh_free( hash_table->timers );
95
-      } /* if (hash_table->timers ) */
65
+      /* deletes all cells from DELETE_LIST list (they are no more accessible from enrys) */
66
+      while( (tl=remove_from_timer_list_from_head( hash_table, DELETE_LIST ))!=0 )
67
+         free_cell( p_cell ) ;
68
+
69
+      /* the mutexs for sync the lists are released*/
70
+      for ( i=0 ; i<NR_OF_TIMER_LISTS ; i++ )
71
+         release_timerlist_lock( &(hash_table->timers[i]) );
96 72
 
97 73
       sh_free( hash_table );
98 74
    }
... ...
@@ -100,6 +76,9 @@ void free_hash_table( struct s_table *hash_table )
100 76
 
101 77
 
102 78
 
79
+
80
+/*
81
+  */
103 82
 struct s_table* init_hash_table()
104 83
 {
105 84
    struct s_table*  hash_table;
... ...
@@ -109,48 +88,26 @@ struct s_table* init_hash_table()
109 88
    /*allocs the table*/
110 89
    hash_table = sh_malloc(  sizeof( struct s_table ) );
111 90
    if ( !hash_table )
112
-	goto error;
91
+      goto error;
113 92
 
114 93
    memset( hash_table, 0, sizeof (struct s_table ) );
115 94
 
116
-   /*inits the time*/
117
-   hash_table->time = 0;
118
-
119
-
120 95
    /* try first allocating all the structures needed for syncing */
121 96
    if (lock_initialize()==-1)
122
-	goto error;
123
-
124
-   /* allocs the entry's table */
125
-    hash_table->entrys  = sh_malloc( TABLE_ENTRIES * sizeof( struct entry )  );
126
-    if ( !hash_table->entrys )
127
-	goto error;
128
-    /* inits the entrys */
129
-    for(  i=0 ; i<TABLE_ENTRIES; i++ )
130
-    {
131
-       hash_table->entrys[i].first_cell = 0;
132
-       hash_table->entrys[i].last_cell = 0;
133
-       hash_table->entrys[i].next_label = 0;
134
-       init_entry_lock( hash_table , (hash_table->entrys)+i );
135
-    }
136
-
137
-   /* allocs the transaction timer's table */
138
-    hash_table->timers  = sh_malloc( NR_OF_TIMER_LISTS * sizeof( struct timer )  );
139
-    if ( !hash_table->timers )
140
-	goto error;
97
+     goto error;
98
+
99
+   /* inits the entrys */
100
+   for(  i=0 ; i<TABLE_ENTRIES; i++ )
101
+      init_entry_lock( hash_table , (hash_table->entrys)+i );
102
+
141 103
    /* inits the timers*/
142
-    for(  i=0 ; i<NR_OF_TIMER_LISTS ; i++ )
143
-    {
144
-       hash_table->timers[i].first_tl = 0;
145
-       hash_table->timers[i].last_tl = 0;
146
-       //init_timerlist_lock( hash_table, (hash_table->timers)+i );
147
-       init_timerlist_lock( hash_table, i );
148
-    }
149
-
150
-//#ifdef THREAD
104
+   for(  i=0 ; i<NR_OF_TIMER_LISTS ; i++ )
105
+      init_timerlist_lock( hash_table, i );
106
+
107
+#ifdef THREAD
151 108
    /* starts the timer thread/ process */
152 109
    pthread_create( thread, NULL, timer_routine, hash_table );
153
-//#endif
110
+#endif
154 111
 
155 112
    return  hash_table;
156 113
 
... ...
@@ -162,58 +119,23 @@ error:
162 119
 
163 120
 
164 121
 
165
-void ref_transaction( struct cell* p_cell)
166
-{
167
-   lock( p_cell->mutex );
168
-   p_cell->ref_counter++;
169
-   unlock( p_cell->mutex );
170
-}
171
-
172
-
173
-void unref_transaction( struct cell* p_cell)
174
-{
175
-   lock( p_cell->mutex );
176
-   p_cell->ref_counter--;
177
-   unlock( p_cell->mutex );
178
-}
179
-
180
-
181
-/* function returns:
182
- *       0 - a new transaction was created
183
- *      -1 - retransmission
184
- *      -2 - error
185
- */
186
-int t_add_transaction( struct s_table* hash_table , struct sip_msg* p_msg )
122
+struct cell*  build_cell( struct s_table* hash_table , struct sip_msg* p_msg )
187 123
 {
188 124
    struct cell*    new_cell;
189
-   struct entry* match_entry;
190
-   int                  hash_index;
191 125
 
192
-   /* it's about the same transaction or not?*/
193
-   if ( global_msg_id != p_msg->id )
194
-   {
195
-      T = (struct cell*)-1;
196
-      global_msg_id = p_msg->id;
197
-   }
198
-
199
-    /* if the transaction is not found yet we are tring to look for it*/
200
-   if ( (int)T==-1 )
201
-      /* if the lookup's result is not 0 means that it's a retransmission */
202
-      if ( t_lookup_request( hash_table , p_msg ) )
203
-         return -1;
204
-
205
-   /* creates a new transaction */
206
-   hash_index   = hash( p_msg->callid , get_cseq(p_msg)->number );
207
-   match_entry = &hash_table->entrys[hash_index];
126
+    /* do we have the source for the build process? */
127
+   if (!p_msg)
128
+      return 0;
208 129
 
130
+   /* allocs a new cell */
209 131
    new_cell = sh_malloc( sizeof( struct cell ) );
210 132
    if  ( !new_cell )
211
-      return -2;
133
+      return 0;
212 134
 
213 135
    /* filling with 0 */
214 136
    memset( new_cell, 0, sizeof( struct cell ) );
215 137
    /* hash index of the entry */
216
-   new_cell->hash_index = hash_index;
138
+   new_cell->hash_index = hash( p_msg->callid , get_cseq(p_msg)->number );
217 139
    /* mutex */
218 140
    init_cell_lock(  new_cell );
219 141
    /* ref counter is 0 */
... ...
@@ -230,621 +152,82 @@ int t_add_transaction( struct s_table* hash_table , struct sip_msg* p_msg )
230 152
    /* all pointers from outbound_request array are NULL */
231 153
    /* all pointers from outbound_response array are NULL */
232 154
 
233
-
234
-   /* critical region - inserting the cell at the end of the list */
235
-   lock( match_entry->mutex );
236
-   new_cell->label = match_entry->next_label++;
237
-   if ( match_entry->last_cell )
238
-   {
239
-      match_entry->last_cell->next_cell = new_cell;
240
-      new_cell->prev_cell = match_entry->last_cell;
241
-   }
242
-   else
243
-      match_entry->first_cell = new_cell;
244
-   match_entry->last_cell = new_cell;
245
-   unlock( match_entry->mutex );
246
-
247
-   T = new_cell;
248
-   return 0;
249
-}
250
-
251
-
252
-/* function returns:
253
- *       0 - transaction wasn't found
254
- *       1 - transaction found
255
- */
256
-int t_lookup_request(  struct s_table* hash_table , struct sip_msg* p_msg )
257
-{
258
-   struct cell      *p_cell;
259
-   struct cell      *tmp_cell;
260
-   unsigned int  hash_index=0;
261
-   unsigned int  isACK = 0;
262
-
263
-   /* it's about the same transaction or not?*/
264
-   if ( global_msg_id != p_msg->id )
265
-   {
266
-      T = (struct cell*)-1;
267
-      global_msg_id = p_msg->id;
268
-   }
269
-
270
-    /* if  T is previous found -> return found */
271
-   if ( (int)T !=-1 && T )
272
-      return 1;
273
-
274
-    /* if T was previous searched and not found -> return not found*/
275
-   if ( !T )
276
-      return 0;
277
-
278
-   /* start searching into the table */
279
-   hash_index = hash( p_msg->callid , get_cseq(p_msg)->number ) ;
280
-   if ( p_msg->first_line.u.request.method_value==METHOD_ACK  )
281
-      isACK = 1;
282
-
283
-   /* all the transactions from the entry are compared */
284
-   p_cell     = hash_table->entrys[hash_index].first_cell;
285
-   tmp_cell = 0;
286
-   while( p_cell )
287
-   {
288
-      /* the transaction is referenceted for reading */
289
-      ref_transaction( p_cell );
290
-
291
-      /* is it the wanted transaction ? */
292
-      if ( !isACK )
293
-      { /* is not an ACK request */
294
-         /* first only the length are checked */
295
-         if ( /*from length*/ p_cell->inbound_request->from->body.len == p_msg->from->body.len )
296
-            if ( /*to length*/ p_cell->inbound_request->to->body.len == p_msg->to->body.len )
297
-                //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) )
298
-                  if ( /*callid length*/ p_cell->inbound_request->callid->body.len == p_msg->callid->body.len )
299
-                     if ( /*cseq length*/ p_cell->inbound_request->cseq->body.len == p_msg->cseq->body.len )
300
-                            /* so far the lengths are the same -> let's check the contents */
301
-                            if ( /*from*/ !memcmp( p_cell->inbound_request->from->body.s , p_msg->from->body.s , p_msg->from->body.len ) )
302
-                               if ( /*to*/ !memcmp( p_cell->inbound_request->to->body.s , p_msg->to->body.s , p_msg->to->body.len)  )
303
-                                  //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 )) )
304
-                                     if ( /*callid*/ !memcmp( p_cell->inbound_request->callid->body.s , p_msg->callid->body.s , p_msg->callid->body.len ) )
305
-                                        if ( /*cseq*/ !memcmp( p_cell->inbound_request->cseq->body.s , p_msg->cseq->body.s , p_msg->cseq->body.len ) )
306
-                                              { /* WE FOUND THE GOLDEN EGG !!!! */
307
-                                                 T = p_cell;
308
-                                                 unref_transaction ( p_cell );
309
-                                                 return 1;
310
-                                              }
311
-      }
312
-      else
313
-      { /* it's a ACK request*/
314
-         /* first only the length are checked */
315
-         if ( /*from length*/ p_cell->inbound_request->from->body.len == p_msg->from->body.len )
316
-            if ( /*to length*/ p_cell->inbound_request->to->body.len == p_msg->to->body.len )
317
-               if ( /*callid length*/ p_cell->inbound_request->callid->body.len == p_msg->callid->body.len )
318
-                  if ( /*cseq_nr length*/ get_cseq(p_cell->inbound_request)->number.len == get_cseq(p_msg)->number.len )
319
-                      if ( /*cseq_method length*/ get_cseq(p_cell->inbound_request)->method.len == 6 /*INVITE*/ )
320
-                         //if ( /*tag length*/ p_cell->tag &&  p_cell->tag->len==p_msg->tag->body.len )
321
-                            /* so far the lengths are the same -> let's check the contents */
322
-                            if ( /*from*/ !memcmp( p_cell->inbound_request->from->body.s , p_msg->from->body.s , p_msg->from->body.len ) )
323
-                               if ( /*to*/ !memcmp( p_cell->inbound_request->to->body.s , p_msg->to->body.s , p_msg->to->body.len)  )
324
-                                  //if ( /*tag*/ !memcmp( p_cell->tag->s , p_msg->tag->body.s , p_msg->tag->body.len ) )
325
-                                     if ( /*callid*/ !memcmp( p_cell->inbound_request->callid->body.s , p_msg->callid->body.s , p_msg->callid->body.len ) )
326
-                                        if ( /*cseq_nr*/ !memcmp( get_cseq(p_cell->inbound_request)->number.s , get_cseq(p_msg)->number.s , get_cseq(p_msg)->number.len ) )
327
-                                           if ( /*cseq_method*/ !memcmp( get_cseq(p_cell->inbound_request)->method.s , "INVITE" , 6 ) )
328
-                                              { /* WE FOUND THE GOLDEN EGG !!!! */
329
-                                                 T = p_cell;
330
-                                                 unref_transaction ( p_cell );
331
-                                                 return 1;
332
-                                              }
333
-      } /* end if is ACK or not*/
334
-      /* next transaction */
335
-      tmp_cell = p_cell;
336
-      p_cell = p_cell->next_cell;
337
-
338
-      /* the transaction is dereferenceted */
339
-      unref_transaction ( tmp_cell );
340
-   }
341
-
342
-   /* no transaction found */
343
-   T = 0;
344
-   return 0;
345
-}
346
-
347
-
348
-
349
-/* function returns:
350
- *       0 - transaction wasn't found
351
- *       T - transaction found
352
- */
353
-struct cell* t_lookupOriginalT(  struct s_table* hash_table , struct sip_msg* p_msg )
354
-{
355
-   struct cell      *p_cell;
356
-   struct cell      *tmp_cell;
357
-   unsigned int  hash_index=0;
358
-
359
-   /* it's a CANCEL request for sure */
360
-
361
-   /* start searching into the table */
362
-   hash_index = hash( p_msg->callid , get_cseq(p_msg)->number  ) ;
363
-
364
-   /* all the transactions from the entry are compared */
365
-   p_cell     = hash_table->entrys[hash_index].first_cell;
366
-   tmp_cell = 0;
367
-   while( p_cell )
368
-   {
369
-      /* the transaction is referenceted for reading */
370
-      ref_transaction( p_cell );
371
-
372
-      /* is it the wanted transaction ? */
373
-      /* first only the length are checked */
374
-      if ( /*from length*/ p_cell->inbound_request->from->body.len == p_msg->from->body.len )
375
-         if ( /*to length*/ p_cell->inbound_request->to->body.len == p_msg->to->body.len )
376
-            //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) )
377
-               if ( /*callid length*/ p_cell->inbound_request->callid->body.len == p_msg->callid->body.len )
378
-                  if ( /*cseq_nr length*/ get_cseq(p_cell->inbound_request)->number.len == get_cseq(p_msg)->number.len )
379
-                      //if ( /*cseq_method length*/ p_cell->inbound_request->cseq_method->body.len != 6 /*CANCEL*/ )
380
-                         if ( /*req_uri length*/ p_cell->inbound_request->first_line.u.request.uri.len == p_msg->first_line.u.request.uri.len )
381
-                             /* so far the lengths are the same -> let's check the contents */
382
-                             if ( /*from*/ !memcmp( p_cell->inbound_request->from->body.s , p_msg->from->body.s , p_msg->from->body.len ) )
383
-                                if ( /*to*/ !memcmp( p_cell->inbound_request->to->body.s , p_msg->to->body.s , p_msg->to->body.len)  )
384
-                                   //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 )) )
385
-                                      if ( /*callid*/ !memcmp( p_cell->inbound_request->callid->body.s , p_msg->callid->body.s , p_msg->callid->body.len ) )
386
-                                          if ( /*cseq_nr*/ !memcmp( get_cseq(p_cell->inbound_request)->number.s , get_cseq(p_msg)->number.s , get_cseq(p_msg)->number.len ) )
387
-                                             if ( /*cseq_method*/ strcmp( get_cseq(p_cell->inbound_request)->method.s , "CANCEL" ) )
388
-                                                if ( /*req_uri*/ memcmp( p_cell->inbound_request->first_line.u.request.uri.s , p_msg->first_line.u.request.uri.s , p_msg->first_line.u.request.uri.len ) )
389
-                                                { /* WE FOUND THE GOLDEN EGG !!!! */
390
-                                                   unref_transaction ( p_cell );
391
-                                                   return p_cell;
392
-                                                }
393
-      /* next transaction */
394
-      tmp_cell = p_cell;
395
-      p_cell = p_cell->next_cell;
396
-
397
-      /* the transaction is dereferenceted */
398
-      unref_transaction ( tmp_cell );
399
-   }
400
-
401
-   /* no transaction found */
402
-   T = 0;
403
-   return 0;
404
-
405
-
406
-   return 0;
407
-}
408
-
409
-
410
-/* function returns:
411
- *       0 - forward successfull
412
- *      -1 - error during forward
413
- */
414
-int t_forward( struct s_table* hash_table , struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int dest_port_param )
415
-{
416
-   /* it's about the same transaction or not? */
417
-   if ( global_msg_id != p_msg->id )
418
-   {
419
-      T = (struct cell*)-1;
420
-      global_msg_id = p_msg->id;
421
-   }
422
-
423
-   /* if  T hasn't been previous searched -> search for it */
424
-   if ( (int)T !=-1 )
425
-      t_lookup_request( hash_table , p_msg );
426
-
427
-   /*if T hasn't been found after all -> return not found (error) */
428
-   if ( !T )
429
-      return -1;
430
-
431
-   /*if it's an ACK and the status is not final or is final, but error the ACK is not forwarded*/
432
-   if ( !memcmp(p_msg->first_line.u.request.method.s,"ACK",3) && (T->status/100)!=2 )
433
-      return 0;
434
-
435
-   /* if it's forwarded for the first time ; else the request is retransmited from the transaction buffer */
436
-   if ( T->outbound_request[0]==NULL )
437
-   {
438
-      unsigned int dest_ip     = dest_ip_param;
439
-      unsigned int dest_port  = dest_port_param;
440
-      unsigned int len;
441
-      char              *buf;
442
-
443
-      /* allocates a new retrans_buff for the outbound request */
444
-      T->outbound_request[0] = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) );
445
-      T->nr_of_outgoings = 1;
446
-
447
-      /* special case : CANCEL */
448
-      if ( p_msg->first_line.u.request.method_value==METHOD_CANCEL  )
449
-      {
450
-         struct cell  *T2;
451
-         /* find original cancelled transaction; if found, use its next-hops; otherwise use those passed by script */
452
-         T2 = t_lookupOriginalT( hash_table , p_msg );
453
-         /* if found */
454
-         if (T2)
455
-         {  /* if in 1xx status, send to the same destination */
456
-            if ( (T2->status/100)==1 )
457
-            {
458
-               dest_ip    = T2->outbound_request[0]->dest_ip;
459
-               dest_port = T2->outbound_request[0]->dest_port;
460
-            }
461
-            else
462
-               /* transaction exists, but nothing to cancel */
463
-             return 0;
464
-         }
465
-      }/* end special case CANCEL*/
466
-
467
-      /* store */
468
-      T->outbound_request[0]->dest_ip    = dest_ip;
469
-      T->outbound_request[0]->dest_port = dest_port;
470
-      // buf = build_message( p_mesg , &len );
471
-      // T->outbound_request[0]->bufflen     = len ;
472
-      // memcpy( T->outbound_request[0]->buffer , buf , len );
473
-   }/* end for the first time */
474
-
475
-   /* send the request */
476
-   // send ( T->outbound_request.buffer , T->outbound_request.dest_ip , T->outbound_request.dest_ip );
477
-
155
+   return new_cell;
478 156
 }
479 157
 
480 158
 
481 159
 
482 160
 
483
-
484
-/*  This function is called whenever a reply for our module is received; we need to register
485
-  *  this function on module initialization;
486
-  *  Returns :   1 - core router stops
487
-  *                    0 - core router relay statelessly
161
+/*  Takes an already created cell and links it into hash table on the
162
+  *  appropiate entry.
488 163
   */
489
-int t_on_reply_received( struct s_table  *hash_table , struct sip_msg  *p_msg )
164
+void    insert_into_hash_table( struct s_table *hash_table,  struct cell * p_cell )
490 165
 {
491
-   unsigned int  branch;
166
+   struct entry* p_entry;
492 167
 
493
-   global_msg_id = p_msg->id;
168
+   /* do we have or not something to insert? */
169
+   if (!p_cell)
170
+      return;
494 171
 
495
-   /* we use label-matching to lookup for T */
496
-   t_reply_matching( hash_table , p_msg , &T , &branch  );
172
+   /* locates the apropiate entry */
173
+   p_entry = &hash_table->entrys[ p_cell->hash_index ];
497 174
 
498
-   /* if no T found ->tell the core router to forward statelessly */
499
-   if ( !T )
500
-      return 0;
175
+   /* critical region - inserting the cell at the end of the list */
176
+   lock( p_entry->mutex );
501 177
 
502
-   /* on a non-200 reply to INVITE, generate local ACK and stop retransmission of the INVITE */
503
-   if ( T->inbound_request->first_line.u.request.method_value==METHOD_INVITE && p_msg->first_line.u.reply.statusclass>2 )
178
+   p_cell->label = p_entry->next_label++;
179
+   if ( p_entry->last_cell )
504 180
    {
505
-      // sendACK   TO DO !!!!!!!!!!
506
-      // remove_from_retransmission_list( T->outbound_request[branch] );     TO DO !!!!!
507
-      t_store_incoming_reply( T , branch , p_msg );
508
-   }
509
-
510
-   #ifdef FORKING
511
-   /* skipped for the moment*/
512
-   #endif
513
-
514
-   /*let's check the current inbound response status (is final or not) */
515
-   if ( T->inbound_response && (T->status/100)>1 )
516
-   {   /*a final reply was already sent upstream */
517
-       /* alway relay 2xx immediately ; drop anything else */
518
-      if ( p_msg->first_line.u.reply.statusclass==2 )
519
-          t_relay_reply( T , branch , p_msg );
520
-       /* nothing to do for the ser core */
521
-      return 1;
181
+      p_entry->last_cell->next_cell = p_cell;
182
+      p_cell->prev_cell = p_entry->last_cell;
522 183
    }
523 184
    else
524
-   {  /* no reply sent yet or sent but not final*/
525
-
526
-      /* stops the request's retransmission*/
527
-      // remove_from_retransmission_list( T->outbound_request[branch] );     TO DO !!!!!
528
-      /* restart retransmission if provisional response came for a non_INVITE -> retrasmit at RT_T2*/
529
-      if ( p_msg->first_line.u.reply.statusclass==1 && T->inbound_request->first_line.u.request.method_value!=METHOD_INVITE )
530
-         /*put_in_retransmission_list( T->trasaction.outbound_request[branch] , RT_T2 ) TO DO !!!!!!!*/ ;
531
-
532
-
533
-      /* relay ringing and OK immediately */
534
-      if ( p_msg->first_line.u.reply.statusclass ==1 || p_msg->first_line.u.reply.statusclass ==2  )
535
-      {
536
-           if ( p_msg->first_line.u.reply.statuscode > T->status )
537
-              t_relay_reply( T , branch , p_msg );
538
-         return 1;
539
-      }
540
-
541
-      /* error final responses are only stored */
542
-      if ( p_msg->first_line.u.reply.statusclass>=3 && p_msg->first_line.u.reply.statusclass<=5 )
543
-      {
544
-         t_store_incoming_reply( T , branch , p_msg );
545
-         if ( t_all_final(T) )
546
-              relay_lowest_reply_upstream( T , p_msg );
547
-         /* nothing to do for the ser core */
548
-         return 1;
549
-      }
550
-
551
-      /* global failure responses relay immediately */
552
-     if ( p_msg->first_line.u.reply.statusclass==6 )
553
-      {
554
-         t_relay_reply( T , branch , p_msg );
555
-         /* nothing to do for the ser core */
556
-         return 1;
557
-      }
558
-   }
559
-}
560
-
561
-
562
-
563
-
564
-/* Retransmits the last sent inbound reply.
565
-  * Returns  -1 -error
566
-  *                0 - OK
567
-  */
568
-int t_retransmit_reply( struct s_table *hash_table , struct sip_msg* p_msg )
569
-{
570
-   t_check( hash_table, p_msg );
571
-
572
-   /* if no transaction exists or no reply to be resend -> out */
573
-   if ( T  && T->inbound_response )
574
-   {
575
-       //sendto(  );   TO DO !!!!!!
576
-      return 0;
577
-   }
578
-
579
-   return -1;
580
-}
581
-
582
-
583
-
584
-
585
-/* ----------------------------HELPER FUNCTIONS-------------------------------- */
586
-
587
-
588
-/* Returns 0 - nothing found
589
-  *              1  - T found
590
-  */
591
-int t_reply_matching( struct s_table *hash_table , struct sip_msg *p_msg , struct cell **p_Trans , unsigned int *p_branch )
592
-{
593
-   struct cell*  p_cell;
594
-   struct cell* tmp_cell;
595
-   unsigned int hash_index = 0;
596
-   unsigned int entry_label  = 0;
597
-   unsigned int branch_id    = 0;
598
-
599
-   /* getting the hash_index from the brach param , via header*/
600
-   // hash_index = get_hash_index( p_msg );   TO DO !!!!
601
-
602
-   /*if the hash index is corect */
603
-   if  ( hash_index>=0 && hash_index<TABLE_ENTRIES-1 )
604
-   {
605
-      /* getting the entry label value */
606
-      // entry_label =  get_entry_label( p_msg );   TO DO !!!!
607
-      /* if the entry label also is corect */
608
-      if  ( entry_label>=0 )
609
-      {
610
-         /* getting the branch_id value */
611
-         // entry_label =  get_branch_id( p_msg );   TO DO !!!!
612
-         /* if the entry label also is corect */
613
-          if  ( branch_id>=0 )
614
-          {
615
-             /*all the cells from the entry are scan to detect an entry_label matching */
616
-             p_cell     = hash_table->entrys[hash_index].first_cell;
617
-             tmp_cell = 0;
618
-            while( p_cell )
619
-             {
620
-                /* the transaction is referenceted for reading */
621
-                ref_transaction( p_cell );
622
-                /* is it the cell with the wanted entry_label? */
623
-                if ( p_cell->label = entry_label )
624
-                   /* has the transaction the wanted branch? */
625
-                   if ( p_cell->nr_of_outgoings>branch_id && p_cell->outbound_request[branch_id] )
626
-                    {/* WE FOUND THE GOLDEN EGG !!!! */
627
-                       p_Trans = &p_cell;
628
-                       *p_branch = branch_id;
629
-                       unref_transaction( p_cell );
630
-                       return 1;
631
-                    }
632
-
633
-               /* next cell */
634
-               tmp_cell = p_cell;
635
-               p_cell = p_cell->next_cell;
636
-
637
-               /* the transaction is dereferenceted */
638
-               unref_transaction( tmp_cell );
639
-             }
640
-          }
641
-      }
642
-   }
643
-
644
-   /* nothing found */
645
-   *p_branch = -1;
646
-   return 0;
647
-}
648
-
649
-
650
-
651
-
652
-/* We like this incoming reply, so, let's store it, we'll decide
653
-  * later what to d with that
654
-  */
655
-int t_store_incoming_reply( struct cell* Trans, unsigned int branch, struct sip_msg* p_msg )
656
-{
657
-   /* if there is a previous reply, replace it */
658
-   if ( Trans->outbound_response[branch] )
659
-      /*free_sip_msg( Trans->outbound_response[branch] ) TO DO*/ ;
660
-   Trans->outbound_response[branch] = sip_msg_cloner( p_msg );
661
-}
662
-
663
-
664
-
665
-
666
-/*  We like this incoming reply and we want ot store it and
667
-  *  to relay it upstream
668
-  */
669
-int t_relay_reply( struct cell* Trans, unsigned int branch, struct sip_msg* p_msg )
670
-{
671
-   t_store_incoming_reply( Trans , branch, p_msg );
672
-   push_reply_from_uac_to_uas( p_msg , branch );
673
-}
674
-
675
-
676
-
677
-
678
-/* Functions update T (T gets either a valid pointer in it or it equals zero) if no transaction
679
-  * for current message exists;
680
-  * Returns 1 if T was modified or 0 if not.
681
-  */
682
-int t_check( struct s_table *hash_table , struct sip_msg* p_msg )
683
-{
684
-   unsigned int branch;
685
-
686
-   /* is T still up-to-date ? */
687
-   if ( p_msg->id != global_msg_id || (int)T==-1 )
688
-   {
689
-      global_msg_id = p_msg->id;
690
-      /* transaction lookup */
691
-     if ( p_msg->first_line.type=SIP_REQUEST )
692
-         t_lookup_request(  hash_table , p_msg );
693
-      else
694
-         t_reply_matching( hash_table , p_msg , &T , &branch );
695
-
696
-      return 1;
697
-   }
698
-
699
-   return 0;
700
-}
701
-
702
-
703
-
704
-
705
-/*  Checks if all the transaction's outbound request has a final response.
706
-  *  Return   1 - all are final
707
-  *                0 - some waitting
708
-  */
709
-int t_all_final( struct cell *Trans )
710
-{
711
-   unsigned int i;
712
-
713
-   for( i=0 ; i<Trans->nr_of_outgoings ; i++  )
714
-      if (  !Trans->outbound_response[i] || (Trans->outbound_response[i]) && Trans->outbound_response[i]->first_line.u.reply.statuscode<200 )
715
-         return 0;
185
+      p_entry->first_cell = p_cell;
186
+   p_entry->last_cell = p_cell;
716 187
 
717
-   return 1;
188
+   unlock( p_entry->mutex );
718 189
 }
719 190
 
720 191
 
721 192
 
722 193
 
723
-/* Picks the lowest code reply and send it upstream.
724
-  *  Returns -1 if no lowest find reply found (all provisional)
194
+/*  Un-link a  cell from hash_table, but the cell itself is not released
725 195
   */
726
-int relay_lowest_reply_upstream( struct cell *Trans , struct sip_msg *p_msg )
727
-{
728
-   unsigned int i            =0 ;
729
-   unsigned int lowest_i = -1;
730
-   int                 lowest_v = 999;
731
-
732
-   for(  ; i<T->nr_of_outgoings ; i++ )
733
-      if ( T->outbound_response[i] && T->outbound_response[i]->first_line.u.reply.statuscode>=200 && T->outbound_response[i]->first_line.u.reply.statuscode<lowest_v )
734
-      {
735
-         lowest_i =i;
736
-         lowest_v = T->outbound_response[i]->first_line.u.reply.statuscode;
737
-      }
738
-
739
-   if ( lowest_i != -1 )
740
-      push_reply_from_uac_to_uas( p_msg ,lowest_i );
741
-
742
-   return lowest_i;
743
-}
744
-
745
-
746
-
747
-
748
-/* Push a previously stored reply from UA Client to UA Server
749
-  * and send it out
750
-  */
751
-int push_reply_from_uac_to_uas( struct sip_msg *p_msg , unsigned int branch )
196
+void remove_from_hash_table( struct s_table *hash_table,  struct cell * p_cell )
752 197
 {
753
-   /* if there is a reply, release the buffer (everything else stays same) */
754
-   if ( T->inbound_response )
755
-   {
756
-      sh_free( T->inbound_response->buffer );
757
-      //release_retransmision.... ????
758
-   }
759
-
760
-
761
-}
762
-
763
-
764
-
198
+   struct entry*  p_entry  = &(hash_table->entrys[p_cell->hash_index]);
765 199
 
200
+   lock( p_entry->mutex );
766 201
 
202
+   if ( p_cell->prev_cell )
203
+      p_cell->prev_cell->next_cell = p_cell->next_cell;
204
+   else
205
+      p_entry->first_cell = p_cell->next_cell;
767 206
 
207
+   if ( p_cell->next_cell )
208
+      p_cell->next_cell->prev_cell = p_cell->prev_cell;
209
+   else
210
+      p_entry->last_cell = p_cell->prev_cell;
768 211
 
769
-
770
-
771
-
772
-
773
-
774
-/*
775
-*   The cell is inserted at the end of the FINAL RESPONSE timer list.
776
-*   The expire time is given by the current time plus the FINAL
777
-    RESPONSE timeout - FR_TIME_OUT
778
-*/
779
-void start_FR_timer( struct s_table* hash_table, struct cell* p_cell )
780
-{
781
-
782
-   /* adds the cell int FINAL RESPONSE timer list*/
783
-   add_to_tail_of_timer_list( hash_table, &(p_cell->tl[FR_TIMER_LIST]), FR_TIMER_LIST, FR_TIME_OUT);
784
-
212
+   unlock( p_entry->mutex );
785 213
 }
786 214
 
787 215
 
788
-/*
789
-*   The cell is inserted at the end of the WAIT timer list. Before adding to the WT list, it's verify if the cell is
790
-*   or not in the FR list (normally it should be there). If it is, it's first removed from FR list and after that
791
-*   added to the WT list.
792
-*   The expire time is given by the current time plus the WAIT timeout - WT_TIME_OUT
793
-*/
794
-
795
-void start_WT_timer( struct s_table* hash_table, struct cell* p_cell )
216
+void ref_cell( struct cell* p_cell)
796 217
 {
797
-   	struct timer* timers= hash_table->timers;
798
-
799
-   	//if is in FR list -> first it must be removed from there
800
-	remove_from_timer_list( hash_table, &(p_cell->tl[FR_TIMER_LIST]), FR_TIMER_LIST );
801
-
802
-   	/* adds the cell int WAIT timer list*/
803
-   	add_to_tail_of_timer_list( hash_table, &(p_cell->tl[WT_TIMER_LIST]), WT_TIMER_LIST, WT_TIME_OUT );
218
+   lock( p_cell->mutex );
219
+   p_cell->ref_counter++;
220
+   unlock( p_cell->mutex );
804 221
 }
805 222
 
806 223
 
807
-void remove_from_hash_table( struct s_table *hash_table,  struct cell * p_cell )
224
+void unref_cell( struct cell* p_cell)
808 225
 {
809
-	struct entry*  p_entry  = &(hash_table->entrys[p_cell->hash_index]);
810
-	lock( p_entry->mutex );
811
-    	if ( p_cell->prev_cell )
812
-         	p_cell->prev_cell->next_cell = p_cell->next_cell;
813
-      	else
814
-         	p_entry->first_cell = p_cell->next_cell;
815
-      	if ( p_cell->next_cell )
816
-         	p_cell->next_cell->prev_cell = p_cell->prev_cell;
817
-      	else
818
-         	p_entry->last_cell = p_cell->prev_cell;
819
-    	unlock( p_entry->mutex );
226
+   lock( p_cell->mutex );
227
+   p_cell->ref_counter--;
228
+   unlock( p_cell->mutex );
820 229
 }
821 230
 
822 231
 
823 232
 
824
-/*
825
-*   prepare for del a transaction ; the transaction is first removed from the hash entry list (oniy the links from
826
-*   cell to list are deleted in order to make the cell unaccessible from the list and in the same time to keep the
827
-*   list accessible from the cell for process that are currently reading the cell). If no process is reading the cell
828
-*   (ref conter is 0) the cell is immediatly deleted. Otherwise it is put in a waitting list (del_hooker list) for
829
-*   future del. This list is veify by the the timer every sec and the cell that finaly have ref_counter 0 are del.
830
-*/
831
-void del_Transaction( struct s_table *hash_table , struct cell * p_cell )
832
-{
833
-    int      ref_counter         = 0;
834
-
835
-    /* the cell is removed from the list */
836
-    remove_from_hash_table( hash_table, p_cell );
837
-
838
-    /* gets the cell's ref counter*/
839
-    lock( p_cell->mutex );
840
-    ref_counter = p_cell->ref_counter;
841
-    unlock( p_cell->mutex );
842
-
843
-    /* if is not refenceted -> is deleted*/
844
-    if ( ref_counter==0 )
845
-       free_cell( p_cell );
846
-     /* else it's added to del hooker list for future del */
847
-    else add_to_tail_of_timer_list( hash_table, &(p_cell->tl[DELETE_LIST]), DELETE_LIST, 0 );
848
-}
849
-
850 233
 
... ...
@@ -99,71 +99,29 @@ typedef struct entry
99 99
 struct s_table
100 100
 {
101 101
    /* table of hash entries; each of them is a list of synonyms  */
102
-   struct entry*   entrys;
102
+   struct entry   entrys[ TABLE_ENTRIES ];
103 103
    /* table of timer lists */
104
-   struct timer*   timers;
105
-   /* retransmission lists */
106
-   struct timer*   retr_timers;
107
-#ifdef THREADS
108
-   pthread_t         timer_thread_id;
109
-#endif
104
+   struct timer   timers[ NR_OF_TIMER_LISTS ];
110 105
    /* current time */
111
-  unsigned int   time;
106
+   unsigned int   time;
112 107
 };
113 108
 
114 109
 
115 110
 
116
-void free_cell( struct cell* dead_cell );                    
117
-struct s_table* init_hash_table();
118
-
119
-void ref_transaction( struct cell* p_cell);
120
-void unref_transaction( struct cell* p_cell);
121
-
122
-void free_hash_table( struct s_table* hash_table );
123
-
124
-
125
-/* function returns:
126
- *       0 - a new transaction was created
127
- *      -1 - retransmission
128
- *      -2 - error
129
- */
130
-int  t_add_transaction( struct s_table* hash_table , struct sip_msg* p_msg );
131
-
132
-
133
-/* function returns:
134
- *       0 - transaction wasn't found
135
- *       1 - transaction found
136
- */
137
-int  t_lookup_request( struct s_table* hash_table , struct sip_msg* p_msg );
138
-
139
-
140
-/* function returns:
141
- *       0 - transaction wasn't found
142
- *       T - transaction found
143
- */
144
-struct cell* t_lookupOriginalT(  struct s_table* hash_table , struct sip_msg* p_msg );
145
-
146
-
147
-/* function returns:
148
- *       0 - forward successfull
149
- *      -1 - error during forward
150
- */
151
-int t_forward( struct s_table* hash_table , struct sip_msg* p_msg , unsigned int dst_ip , unsigned int dst_port);
152 111
 
153 112
 
113
+struct s_table* init_hash_table();
114
+void                  free_hash_table( struct s_table* hash_table );
154 115
 
155
-/*  This function is called whenever a reply for our module is received; we need to register
156
-  *  this function on module initialization;
157
-  *  Returns :   1 - core router stops
158
-  *                    0 - core router relay statelessly
159
-  */
160
-int t_on_reply_received( struct s_table  *hash_table , struct sip_msg  *p_msg ) ;
116
+void                free_cell( struct cell* dead_cell );
117
+struct cell*  build_cell( struct s_table* hash_table , struct sip_msg* p_msg );
161 118
 
119
+void remove_from_hash_table( struct s_table *hash_table,  struct cell * p_cell );
120
+void    insert_into_hash_table( struct s_table *hash_table,  struct cell * p_cell );
162 121
 
122
+void      ref_cell( struct cell* p_cell);
123
+void unref_cell( struct cell* p_cell);
163 124
 
164
-/* Retransmits the last sent inbound reply.
165
-  */
166
-int t_retransmit_reply( struct s_table * , struct sip_msg *  );
167 125
 
168 126
 
169 127
 #endif
... ...
@@ -56,11 +56,11 @@ int lock_initialize()
56 56
 		goto error;
57 57
 	}
58 58
 
59
-	/* message retransmission timers */
59
+	/* message retransmission timers
60 60
         if ((retrasmission_timer_semaphore=init_semaphore_set( NR_OF_RT_LISTS) ) < 0) {
61 61
                 DBG("retransmission timer semaphore initialization failure\n");
62 62
                 goto error;
63
-        }
63
+        } */
64 64
 
65 65
 
66 66
 	i=SEM_MIN;
... ...
@@ -226,18 +226,18 @@ int init_timerlist_lock( struct s_table* hash_table, enum lists timerlist_id)
226 226
 	hash_table->timers[timerlist_id].mutex.semaphore_set=transaction_timer_semaphore;
227 227
 	hash_table->timers[timerlist_id].mutex.semaphore_index=timerlist_id;
228 228
 }
229
-
229
+/*
230 230
 int init_retr_timer_lock( struct s_table* hash_table, enum retransmission_lists list_id )
231 231
 {
232 232
 	hash_table->retr_timers[list_id].mutex.semaphore_set=retrasmission_timer_semaphore;
233 233
  	hash_table->retr_timers[list_id].mutex.semaphore_index=list_id;
234 234
 }
235
-
235
+*/
236 236
 
237 237
 int release_cell_lock( struct cell *cell )
238 238
 {
239 239
 	/* don't do anything here -- the init_*_lock procedures
240
-	   just advised on usage of shared semaphores but did not 
240
+	   just advised on usage of shared semaphores but did not
241 241
 	   generate them
242 242
 	*/
243 243
 }
... ...
@@ -250,7 +250,8 @@ release_timerlist_lock( struct timer *timerlist )
250 250
 {
251 251
 	/* the same as above */
252 252
 }
253
+/*
253 254
 int release_retr_timer_lock( struct timer *timerlist )
254 255
 {
255
-	
256
-}
256
+
257
+} */
... ...
@@ -31,7 +31,7 @@ int change_semaphore( ser_lock_t s  , int val );
31 31
 int init_cell_lock( struct cell *cell );
32 32
 int init_entry_lock( struct s_table* hash_table, struct entry *entry );
33 33
 int init_timerlist_lock( struct s_table* hash_table, enum lists timerlist_id);
34
-int init_retr_timer_lock( struct s_table* hash_table, enum retransmission_lists list_id );
34
+//int init_retr_timer_lock( struct s_table* hash_table, enum retransmission_lists list_id );
35 35
 
36 36
 int release_cell_lock( struct cell *cell );
37 37
 int release_entry_lock( struct entry *entry );
... ...
@@ -7,7 +7,7 @@ enum lists { RETRASMISSIONS_LIST, FR_TIMER_LIST, WT_TIMER_LIST, DELETE_LIST, NR_
7 7
    periods; that allows us to keep the lists ordered while just adding
8 8
    new items to list's tail (FIFO)
9 9
 */
10
-enum retransmission_lists { RT_T1_TO1, RT_T1_TO_2, RT_T1_TO_3, RT_T2, NR_OF_RT_LISTS };
10
+//enum retransmission_lists { RT_T1_TO1, RT_T1_TO_2, RT_T1_TO_3, RT_T2, NR_OF_RT_LISTS };
11 11
 
12 12
 
13 13
 /* FINAL_RESPONSE_TIMER ... tells how long should the transaction engine