Bogdan-Andrei Iancu преди 24 години
родител
ревизия
e057a62e1c
променени са 6 файла, в които са добавени 117 реда и са изтрити 45 реда
  1. 1 1
      Makefile.defs
  2. 10 4
      modules/tm/h_table.c
  3. 3 4
      modules/tm/h_table.h
  4. 72 31
      modules/tm/t_funcs.c
  5. 28 3
      modules/tm/timer.c
  6. 3 2
      t_debug.cfg

+ 1 - 1
Makefile.defs

@@ -44,7 +44,7 @@ ARCH = $(shell uname -s)
 #		malloc etc.)
 #		malloc etc.)
 DEFS= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
 DEFS= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
 	 -DDNS_IP_HACK  -DSHM_MEM \
 	 -DDNS_IP_HACK  -DSHM_MEM \
-	 -DPKG_MALLOC -DDBG_QM_MALLOC -DNODEBUG
+	 -DPKG_MALLOC #-DDBG_QM_MALLOC -DNODEBUG
 #-DEXTRA_DEBUG
 #-DEXTRA_DEBUG
 # -DUSE_SHM_MEM
 # -DUSE_SHM_MEM
 #-DNO_DEBUG 
 #-DNO_DEBUG 

+ 10 - 4
modules/tm/h_table.c

@@ -16,26 +16,29 @@ void free_cell( struct cell* dead_cell )
    struct retrans_buff* rb;
    struct retrans_buff* rb;
    char *b;
    char *b;
 
 
-
-   /* UA Server */ 
+   DBG("DEBUG: free_cell: start\n");
+   /* UA Server */
+   DBG("DEBUG: free_cell: inbound request %p\n",dead_cell->inbound_request);
    if ( dead_cell->inbound_request )
    if ( dead_cell->inbound_request )
       sip_msg_free( dead_cell->inbound_request );
       sip_msg_free( dead_cell->inbound_request );
+   DBG("DEBUG: free_cell: outbound response %p\n",dead_cell->outbound_response);
    if ( dead_cell->outbound_response )
    if ( dead_cell->outbound_response )
    {
    {
       b = dead_cell->outbound_response->retr_buffer ;
       b = dead_cell->outbound_response->retr_buffer ;
       dead_cell->outbound_response->retr_buffer = NULL;
       dead_cell->outbound_response->retr_buffer = NULL;
       sh_free( b );
       sh_free( b );
 
 
-      rb = dead_cell->outbound_response; 
+      rb = dead_cell->outbound_response;
       dead_cell->outbound_response = NULL;
       dead_cell->outbound_response = NULL;
       sh_free( rb );
       sh_free( rb );
-      
+
    }
    }
 
 
   /* UA Clients */
   /* UA Clients */
    for ( i =0 ; i<dead_cell->nr_of_outgoings;  i++ )
    for ( i =0 ; i<dead_cell->nr_of_outgoings;  i++ )
    {
    {
       /* outbound requests*/
       /* outbound requests*/
+      DBG("DEBUG: free_cell: outbound_request[%d] %p\n",i,dead_cell->outbound_request[i]);
       if ( dead_cell->outbound_request[i] )
       if ( dead_cell->outbound_request[i] )
       {
       {
 	 b = dead_cell->outbound_request[i]->retr_buffer;
 	 b = dead_cell->outbound_request[i]->retr_buffer;
@@ -47,6 +50,7 @@ void free_cell( struct cell* dead_cell )
          sh_free( rb );
          sh_free( rb );
       }
       }
       /* outbound requests*/
       /* outbound requests*/
+      DBG("DEBUG: free_cell: inbound_response[%d] %p\n",i,dead_cell->inbound_response[i]);
       if ( dead_cell -> inbound_response[i] )
       if ( dead_cell -> inbound_response[i] )
          sip_msg_free( dead_cell->inbound_response[i] );
          sip_msg_free( dead_cell->inbound_response[i] );
    }
    }
@@ -54,6 +58,7 @@ void free_cell( struct cell* dead_cell )
    release_cell_lock( dead_cell );
    release_cell_lock( dead_cell );
    /* the cell's body */
    /* the cell's body */
    sh_free( dead_cell );
    sh_free( dead_cell );
+   DBG("DEBUG: free_cell: start\n");
 }
 }
 
 
 
 
@@ -170,6 +175,7 @@ struct cell*  build_cell( struct sip_msg* p_msg )
    /* all pointers from outbound_request array are NULL */
    /* all pointers from outbound_request array are NULL */
    /* all pointers from outbound_response array are NULL */
    /* all pointers from outbound_response array are NULL */
    /*init the links with the canceled / canceler transaction */
    /*init the links with the canceled / canceler transaction */
+   new_cell->relaied_reply_branch   = -1;
    new_cell->T_canceled  = T_UNDEFINED;
    new_cell->T_canceled  = T_UNDEFINED;
    new_cell->T_canceler  = T_UNDEFINED;
    new_cell->T_canceler  = T_UNDEFINED;
 
 

+ 3 - 4
modules/tm/h_table.h

@@ -93,20 +93,19 @@ typedef struct cell
    struct cell *T_canceled;
    struct cell *T_canceled;
    struct cell *T_canceler;
    struct cell *T_canceler;
 
 
-   /*if the request received an ACK - used only by INVITE*/
-   unsigned int isACKed;
-
    /* usefull data */
    /* usefull data */
    /* UA Server */
    /* UA Server */
    struct sip_msg         *inbound_request;
    struct sip_msg         *inbound_request;
    struct retrans_buff   *outbound_response;
    struct retrans_buff   *outbound_response;
    unsigned int             status;
    unsigned int             status;
    str*                             tag;
    str*                             tag;
-   /* array of outgoing requests and its responses */
+   unsigned int             inbound_request_isACKed;
+   int                              relaied_reply_branch;
    int                               nr_of_outgoings;
    int                               nr_of_outgoings;
    /* UA Clients */
    /* UA Clients */
    struct retrans_buff   *outbound_request[ MAX_FORK ];
    struct retrans_buff   *outbound_request[ MAX_FORK ];
    struct sip_msg          *inbound_response[ MAX_FORK ];
    struct sip_msg          *inbound_response[ MAX_FORK ];
+   unsigned int             outbound_request_isACKed[MAX_FORK];
 }cell_type;
 }cell_type;
 
 
 
 

+ 72 - 31
modules/tm/t_funcs.c

@@ -6,28 +6,30 @@
 #include "../../timer.h"
 #include "../../timer.h"
 
 
 #define stop_RETR_and_FR_timers(h_table,p_cell)    \
 #define stop_RETR_and_FR_timers(h_table,p_cell)    \
-	do{ int ijk; \
+	{ int ijk; \
+		DBG("DEBUG:stop_RETR_and_FR_timers : start \n");\
 		if ( (p_cell)->outbound_response )  {  \
 		if ( (p_cell)->outbound_response )  {  \
-			remove_from_timer_list( \
-				(h_table) , \
+			remove_from_timer_list( (h_table) , \
 				(&((p_cell)->outbound_response->tl[RETRASMISSIONS_LIST])), \
 				(&((p_cell)->outbound_response->tl[RETRASMISSIONS_LIST])), \
-				RETRASMISSIONS_LIST\
-			); \
+				RETRASMISSIONS_LIST ); \
 			remove_from_timer_list( (h_table), \
 			remove_from_timer_list( (h_table), \
-					(&((p_cell)->outbound_response->tl[FR_TIMER_LIST])), \
-					FR_TIMER_LIST );\
+				(&((p_cell)->outbound_response->tl[FR_TIMER_LIST])), \
+				FR_TIMER_LIST );\
 		} \
 		} \
+		DBG("DEBUG:stop_RETR_and_FR_timers : %d \n",(p_cell)->nr_of_outgoings);\
 		for( ijk=0 ; ijk<(p_cell)->nr_of_outgoings ; ijk++ )  { \
 		for( ijk=0 ; ijk<(p_cell)->nr_of_outgoings ; ijk++ )  { \
-			remove_from_timer_list( \
-				(h_table) , \
+			DBG("DEBUG:stop_RETR_and_FR_timers : branch[%d] RETR\n",ijk);\
+			remove_from_timer_list( (h_table) , \
 				(&((p_cell)->outbound_request[ijk]->tl[RETRASMISSIONS_LIST])),\
 				(&((p_cell)->outbound_request[ijk]->tl[RETRASMISSIONS_LIST])),\
-				RETRASMISSIONS_LIST \
-			); \
+				RETRASMISSIONS_LIST ); \
+			DBG("DEBUG:stop_RETR_and_FR_timers : branch[%d] FR\n",ijk);\
 			remove_from_timer_list( (h_table) , \
 			remove_from_timer_list( (h_table) , \
 				(&((p_cell)->outbound_request[ijk]->tl[FR_TIMER_LIST])), \
 				(&((p_cell)->outbound_request[ijk]->tl[FR_TIMER_LIST])), \
 				FR_TIMER_LIST ); \
 				FR_TIMER_LIST ); \
+			DBG("DEBUG:stop_RETR_and_FR_timers : branch]%d] done\n",ijk);\
 		} \
 		} \
-	}while(0)
+		DBG("DEBUG:stop_RETR_and_FR_timers : stop\n");\
+	}
 
 
 
 
 #define insert_into_timer(hash_table,new_tl,list_id,time_out) \
 #define insert_into_timer(hash_table,new_tl,list_id,time_out) \
@@ -79,9 +81,11 @@ void tm_shutdown()
     struct timer_link  *tl, *tmp;
     struct timer_link  *tl, *tmp;
     int i;
     int i;
 
 
+    DBG("DEBUG: tm_shutdown : start\n");
     /*remember the DELETE LIST */
     /*remember the DELETE LIST */
     tl = hash_table->timers[DELETE_LIST].first_tl;
     tl = hash_table->timers[DELETE_LIST].first_tl;
 
 
+    DBG("DEBUG: tm_shutdown : empting DELETE list\n");
     /*unlink the lists*/
     /*unlink the lists*/
     for( i=NR_OF_TIMER_LISTS ; i>=0 ; i-- )
     for( i=NR_OF_TIMER_LISTS ; i>=0 ; i-- )
     {
     {
@@ -94,7 +98,10 @@ void tm_shutdown()
     for(   ;  tl  ;  tmp=tl->next_tl , free_cell((struct cell*)tl->payload) , tl=tmp );
     for(   ;  tl  ;  tmp=tl->next_tl , free_cell((struct cell*)tl->payload) , tl=tmp );
 
 
     /* destroy the hash table */
     /* destroy the hash table */
+    DBG("DEBUG: tm_shutdown : empting hash table\n");
     free_hash_table( hash_table );
     free_hash_table( hash_table );
+
+    DBG("DEBUG: tm_shutdown : done\n");
 }
 }
 
 
 
 
@@ -292,7 +299,9 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
       return 1;
       return 1;
    }
    }
 
 
-   /* if it's forwarded for the first time ; else the request is retransmited from the transaction buffer */
+   /* if it's forwarded for the first time ; else the request is retransmited from the transaction buffer
+     * when forwarding an ACK, this condition will br all the time false because
+     * the forwarded INVITE is in the retransmission buffer */
    if ( T->outbound_request[branch]==NULL )
    if ( T->outbound_request[branch]==NULL )
    {
    {
       DBG("DEBUG: t_forward: first time forwarding\n");
       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
       /* allocates a new retrans_buff for the outbound request */
       /* allocates a new retrans_buff for the outbound request */
       DBG("DEBUG: t_forward: building outbound request\n");
       DBG("DEBUG: t_forward: building outbound request\n");
       T->outbound_request[branch] = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) );
       T->outbound_request[branch] = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) );
-      if (!T->outbound_request[branch]) {
+      if (!T->outbound_request[branch])
+      {
         LOG(L_ERR, "ERROR: t_forward: out of shmem\n");
         LOG(L_ERR, "ERROR: t_forward: out of shmem\n");
 	goto error;
 	goto error;
       }
       }
@@ -364,9 +374,18 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
       insert_into_timer( hash_table , (&(T->outbound_request[branch]->tl[RETRASMISSIONS_LIST])), RETRASMISSIONS_LIST , RETR_T1 );
       insert_into_timer( hash_table , (&(T->outbound_request[branch]->tl[RETRASMISSIONS_LIST])), RETRASMISSIONS_LIST , RETR_T1 );
    }/* end for the first time */
    }/* end for the first time */
 
 
-    /* if we are forwarding a CANCEL*/
+   /* if we are forwarding an ACK*/
+   if (  p_msg->first_line.u.request.method_value==METHOD_ACK &&
+   T->relaied_reply_branch>=0 && T->relaied_reply_branch<=T->nr_of_outgoings)
+   {
+      DBG("DEBUG: t_forward: forwarding ACK [%d]\n",T->relaied_reply_branch);
+      t_build_and_send_ACK( T, branch , T->inbound_response[T->relaied_reply_branch] );
+      T->inbound_request_isACKed = 1;
+     return 1;
+   } else /* if we are forwarding a CANCEL*/
    if (  p_msg->first_line.u.request.method_value==METHOD_CANCEL )
    if (  p_msg->first_line.u.request.method_value==METHOD_CANCEL )
    {
    {
+      DBG("DEBUG: t_forward: forwarding CANCEL\n");
        /* if no transaction to CANCEL */
        /* if no transaction to CANCEL */
       /* or if the canceled transaction has a final status -> drop the CANCEL*/
       /* or if the canceled transaction has a final status -> drop the CANCEL*/
       if ( T->T_canceled==T_NULL || T->T_canceled->status>=200)
       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 )
    if ( !T->inbound_response[branch] && p_msg->first_line.u.reply.statusclass==1 && T->inbound_request->first_line.u.request.method_value==METHOD_INVITE )
    if ( !T->inbound_response[branch] && p_msg->first_line.u.reply.statusclass==1 && T->inbound_request->first_line.u.request.method_value==METHOD_INVITE )
       insert_into_timer( hash_table , (&(T->outbound_request[branch]->tl[FR_TIMER_LIST])) , FR_TIMER_LIST , INV_FR_TIME_OUT);
       insert_into_timer( hash_table , (&(T->outbound_request[branch]->tl[FR_TIMER_LIST])) , FR_TIMER_LIST , INV_FR_TIME_OUT);
 
 
-   /* on a non-200 reply to INVITE, generate local ACK */
-   if ( T->inbound_request->first_line.u.request.method_value==METHOD_INVITE && p_msg->first_line.u.reply.statusclass>2 )
+   /* get response for INVITE */
+   if ( T->inbound_request->first_line.u.request.method_value==METHOD_INVITE )
    {
    {
-      DBG("DEBUG: t_on_reply_received: >=3xx reply to INVITE: send ACK\n");
-      t_build_and_send_ACK( T , branch , p_msg );
+       if ( T->outbound_request_isACKed[branch] )
+       {   /*retransmit*/
+           udp_send( T->outbound_request[branch]->retr_buffer, T->outbound_request[branch]->bufflen,
+             (struct sockaddr*)&(T->outbound_request[branch]->to) , sizeof(struct sockaddr_in) );
+       }
+       else if (p_msg->first_line.u.reply.statusclass>2 )
+       {   /*on a non-200 reply to INVITE*/
+           DBG("DEBUG: t_on_reply_received: >=3xx reply to INVITE: send ACK\n");
+           if ( t_build_and_send_ACK( T , branch , p_msg )==-1)
+           {
+               LOG( L_ERR , "ERROR: t_on_reply_received: unable to send ACK\n" );
+               return 0;
+           }
+       }
    }
    }
 
 
    #ifdef FORKING
    #ifdef FORKING
@@ -543,21 +574,20 @@ int t_on_reply_received( struct sip_msg  *p_msg )
       insert_into_timer( hash_table , (&(T->outbound_request[branch]->tl[RETRASMISSIONS_LIST])) , RETRASMISSIONS_LIST , RETR_T2 );
       insert_into_timer( hash_table , (&(T->outbound_request[branch]->tl[RETRASMISSIONS_LIST])) , RETRASMISSIONS_LIST , RETR_T2 );
    }
    }
 
 
-   /*store the inbound reply*/
-   /* t_store_incoming_reply( T , branch , p_msg ); */
-   /* if there is a previous reply, replace it */
+   /*store the inbound reply - if there is a previous reply, replace it */
    if ( T->inbound_response[branch] ) {
    if ( T->inbound_response[branch] ) {
       sip_msg_free( T->inbound_response[branch] ) ;
       sip_msg_free( T->inbound_response[branch] ) ;
-      DBG("DEBUG: t_store_incoming_reply: sip_msg_free done....\n");
+      DBG("DEBUG: t_store_incoming_reply: previous inbound reply freed....\n");
    }
    }
    T->inbound_response[branch] = clone;
    T->inbound_response[branch] = clone;
-   T->status = p_msg->first_line.u.reply.statuscode;
 
 
    if ( p_msg->first_line.u.reply.statusclass>=3 && p_msg->first_line.u.reply.statusclass<=5 )
    if ( p_msg->first_line.u.reply.statusclass>=3 && p_msg->first_line.u.reply.statusclass<=5 )
    {
    {
-      if ( t_all_final(T) && relay_lowest_reply_upstream( T , p_msg ) == -1 && clone ) {
-	T->inbound_response[branch]=NULL;
+      if ( t_all_final(T) && relay_lowest_reply_upstream( T , p_msg )==-1 && clone )
+      {
+        T->inbound_response[branch]=NULL;
         sip_msg_free( clone );
         sip_msg_free( clone );
+       DBG("DEBUG: t_store_incoming_reply: DONE WITH ERROR!! :((((((((((((((((((((((((((((\n");
         return -1;
         return -1;
       }
       }
    }
    }
@@ -571,7 +601,9 @@ int t_on_reply_received( struct sip_msg  *p_msg )
    }
    }
 
 
    /* nothing to do for the ser core */
    /* nothing to do for the ser core */
-    return 0;
+
+   DBG("DEBUG: t_store_incoming_reply: DONE WITH SUCCESS!! :)))))))))))))))))))))))\n");
+   return 0;
 }
 }
 
 
 
 
@@ -1018,7 +1050,7 @@ int relay_lowest_reply_upstream( struct cell *Trans , struct sip_msg *p_msg )
 
 
    DBG("DEBUG: relay_lowest_reply_upstream: lowest reply [%d]=%d\n",lowest_i,lowest_v);
    DBG("DEBUG: relay_lowest_reply_upstream: lowest reply [%d]=%d\n",lowest_i,lowest_v);
 
 
-   if ( lowest_i != -1 && push_reply_from_uac_to_uas( T ,lowest_i ) != -1 )
+   if ( lowest_i != -1 && push_reply_from_uac_to_uas( T ,lowest_i ) == -1 )
 	return -1;
 	return -1;
 
 
    return lowest_i;
    return lowest_i;
@@ -1070,7 +1102,7 @@ int push_reply_from_uac_to_uas( struct cell* trans , unsigned int branch )
       }
       }
    }
    }
 
 
-   /*  */
+   /*  generate the retrans buffer */
    buf = build_res_buf_from_sip_res ( trans->inbound_response[branch], &len);
    buf = build_res_buf_from_sip_res ( trans->inbound_response[branch], &len);
    if (!buf) {
    if (!buf) {
 	LOG(L_ERR, "ERROR: push_reply_from_uac_to_uas: no shmem for outbound reply buffer\n");
 	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 )
    memcpy( trans->outbound_response->retr_buffer , buf , len );
    memcpy( trans->outbound_response->retr_buffer , buf , len );
    free( buf ) ;
    free( buf ) ;
 
 
-   /* start/stops the proper timers*/
+   /* update the status*/
+   trans->status = trans->inbound_response[branch]->first_line.u.reply.statuscode;
+   if ( trans->inbound_response[branch]->first_line.u.reply.statuscode>=200 &&
+         trans->relaied_reply_branch==-1 )
+       trans->relaied_reply_branch = branch;
+
+    /* start/stops the proper timers*/
    t_update_timers_after_sending_reply( T->outbound_response );
    t_update_timers_after_sending_reply( T->outbound_response );
 
 
    /*send the reply*/
    /*send the reply*/
    t_retransmit_reply( trans->inbound_response[branch], 0 , 0 );
    t_retransmit_reply( trans->inbound_response[branch], 0 , 0 );
-
    return 1;
    return 1;
 }
 }
 
 
@@ -1355,6 +1392,7 @@ void retransmission_handler( void *attr)
 
 
    /* re-insert into RETRASMISSIONS_LIST */
    /* re-insert into RETRASMISSIONS_LIST */
    insert_into_timer( hash_table , (&(r_buf->tl[RETRASMISSIONS_LIST])) , RETRASMISSIONS_LIST , r_buf->timeout_value );
    insert_into_timer( hash_table , (&(r_buf->tl[RETRASMISSIONS_LIST])) , RETRASMISSIONS_LIST , r_buf->timeout_value );
+   DBG("DEBUG: retransmission_handler : done\n");
 }
 }
 
 
 
 
@@ -1378,6 +1416,7 @@ void final_response_handler( void *attr)
       DBG("DEBUG: final_response_handler : cansel transaction->put on wait\n");
       DBG("DEBUG: final_response_handler : cansel transaction->put on wait\n");
       t_put_on_wait(  r_buf->my_T );
       t_put_on_wait(  r_buf->my_T );
    }
    }
+   DBG("DEBUG: final_response_handler : done\n");
 }
 }
 
 
 
 
@@ -1395,6 +1434,7 @@ void wait_handler( void *attr)
    stop_RETR_and_FR_timers(hash_table,p_cell) ;
    stop_RETR_and_FR_timers(hash_table,p_cell) ;
    /* put it on DEL_LIST - sch for del */
    /* put it on DEL_LIST - sch for del */
     add_to_tail_of_timer( hash_table, (&(p_cell->dele_tl)), DELETE_LIST, DEL_TIME_OUT );
     add_to_tail_of_timer( hash_table, (&(p_cell->dele_tl)), DELETE_LIST, DEL_TIME_OUT );
+   DBG("DEBUG: wait_handler : done\n");
 }
 }
 
 
 
 
@@ -1417,6 +1457,7 @@ void delete_handler( void *attr)
        /* else it's readded to del list for future del */
        /* else it's readded to del list for future del */
        add_to_tail_of_timer( hash_table, (&(p_cell->dele_tl)), DELETE_LIST, DEL_TIME_OUT );
        add_to_tail_of_timer( hash_table, (&(p_cell->dele_tl)), DELETE_LIST, DEL_TIME_OUT );
     }
     }
+    DBG("DEBUG: delete_handler : done\n");
 }
 }
 
 
 
 

+ 28 - 3
modules/tm/timer.c

@@ -7,6 +7,20 @@
 #include "../../dprint.h"
 #include "../../dprint.h"
 
 
 
 
+void print_timer_list(struct s_table* hash_table, int list_id)
+{
+   struct timer* timer_list=&(hash_table->timers[ list_id ]);
+   struct timer_link *tl ;
+
+   tl = timer_list->first_tl;
+   while (tl)
+   {
+      DBG("DEBUG: print_timer_list[%d]: %p, next=%p \n",list_id, tl, tl->next_tl);
+      tl = tl->next_tl;
+   }
+}
+
+
 void remove_from_timer_list_dummy( struct s_table* hash_table , struct timer_link* tl , int list_id)
 void remove_from_timer_list_dummy( struct s_table* hash_table , struct timer_link* tl , int list_id)
 {
 {
    struct timer* timer_list=&(hash_table->timers[ list_id ]);
    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*
        timer_list->first_tl = tl;
        timer_list->first_tl = tl;
        timer_list->last_tl = tl;
        timer_list->last_tl = tl;
    }
    }
+
+   //print_timer_list(hash_table, list_id);
    /* give the list lock away */
    /* give the list lock away */
    unlock( timer_list->mutex );
    unlock( timer_list->mutex );
 }
 }
@@ -105,6 +121,7 @@ void insert_into_timer_list( struct s_table* hash_table , struct timer_link* new
        timer_list->first_tl = new_tl;
        timer_list->first_tl = new_tl;
     new_tl->next_tl = tl;
     new_tl->next_tl = tl;
 
 
+   //print_timer_list(hash_table, list_id);
    /* give the list lock away */
    /* give the list lock away */
     unlock( timer_list->mutex );
     unlock( timer_list->mutex );
 }
 }
@@ -127,6 +144,7 @@ void remove_from_timer_list( struct s_table* hash_table , struct timer_link* tl
       remove_from_timer_list_dummy( hash_table , tl , list_id);
       remove_from_timer_list_dummy( hash_table , tl , list_id);
    }
    }
 
 
+   //print_timer_list(hash_table, list_id);
    /* give the list lock away */
    /* give the list lock away */
    unlock( timer_list->mutex );
    unlock( timer_list->mutex );
 }
 }
@@ -139,8 +157,9 @@ void remove_from_timer_list( struct s_table* hash_table , struct timer_link* tl
 struct timer_link  *check_and_split_time_list( struct s_table* hash_table, int list_id ,int time)
 struct timer_link  *check_and_split_time_list( struct s_table* hash_table, int list_id ,int time)
 {
 {
    struct timer* timer_list=&(hash_table->timers[ list_id ]);
    struct timer* timer_list=&(hash_table->timers[ list_id ]);
-   struct timer_link *tl ;
+   struct timer_link *tl , *tmp;
 
 
+   //DBG("DEBUG : check_and_split_time_list: start\n");
    /* the entire timer list is locked now -- noone else can manipulate it */
    /* the entire timer list is locked now -- noone else can manipulate it */
    lock( timer_list->mutex );
    lock( timer_list->mutex );
 
 
@@ -162,19 +181,24 @@ struct timer_link  *check_and_split_time_list( struct s_table* hash_table, int l
     {
     {
       tl = timer_list->first_tl;
       tl = timer_list->first_tl;
       timer_list->first_tl = timer_list->last_tl = 0;
       timer_list->first_tl = timer_list->last_tl = 0;
-     goto exit;
+      //DBG("DEBUG : check_and_split_time_list: done, EVERY returns %p , list=%p\n",tl,timer_list->first_tl);
+      goto exit;
     }
     }
 
 
     /*I have to split it somewhere in the middle */
     /*I have to split it somewhere in the middle */
     tl->prev_tl->next_tl=0;
     tl->prev_tl->next_tl=0;
     tl->prev_tl = 0;
     tl->prev_tl = 0;
+    tmp = timer_list->first_tl;
     timer_list->first_tl = tl;
     timer_list->first_tl = tl;
-    tl = timer_list->first_tl;
+    tl = tmp;
+   //DBG("DEBUG : check_and_split_time_list: done, SPLIT returns %p , list=%p\n",tl,timer_list->first_tl);
 
 
 exit:
 exit:
    /* give the list lock away */
    /* give the list lock away */
    unlock( timer_list->mutex );
    unlock( timer_list->mutex );
 
 
+   //DBG("DEBUG : check_and_split_time_list: done, returns %p\n",tl);
+   //print_timer_list(hash_table, list_id);
    return tl;
    return tl;
 }
 }
 
 
@@ -198,6 +222,7 @@ void timer_routine(unsigned int ticks , void * attr)
       {
       {
          tmp_tl = tl->next_tl;
          tmp_tl = tl->next_tl;
          tl->next_tl = tl->prev_tl =0 ;
          tl->next_tl = tl->prev_tl =0 ;
+         DBG("DEBUG: timer routine: timer[%d] , tl=%p next=%p\n",id,tl,tmp_tl);
          timers[id].timeout_handler( tl->payload );
          timers[id].timeout_handler( tl->payload );
          tl = tmp_tl;
          tl = tmp_tl;
       }
       }

+ 3 - 2
t_debug.cfg

@@ -24,6 +24,7 @@ route{
 	if ( t_lookup_request()) {
 	if ( t_lookup_request()) {
 		if ( method=="ACK" )	{
 		if ( method=="ACK" )	{
 			log("SER: ACK received -> t_release\n");
 			log("SER: ACK received -> t_release\n");
+			t_forward("iptel.org", "5060" );
 			t_release();
 			t_release();
 		} else {
 		} else {
 			t_retransmit_reply();
 			t_retransmit_reply();
@@ -39,7 +40,7 @@ route{
 			log("SER: new transaction\n");
 			log("SER: new transaction\n");
 			t_send_reply("100", "trying -- your call is important to us");
 			t_send_reply("100", "trying -- your call is important to us");
 		};
 		};
-		rewritehost("iptel.org");
+		#rewritehost("iptel.org");
 		# XXX ... it wants me to put port nr in ""
 		# XXX ... it wants me to put port nr in ""
 		#t_forward("benetnash.fokus.gmd.de", "5080" );
 		#t_forward("benetnash.fokus.gmd.de", "5080" );
 		#t_forward("iptel.org", "5060" );
 		#t_forward("iptel.org", "5060" );
@@ -48,5 +49,5 @@ route{
 		# t_forward("fox.iptel.org" );
 		# t_forward("fox.iptel.org" );
 		# XXX t_forward_uri ... not done yet
 		# XXX t_forward_uri ... not done yet
 	};
 	};
-		
+
 }
 }