Hello,

let's see with this patch. I had no time to test it by myself, so your help is very much appreciated.

You have to revert the previous ones.

Thanks,
Daniel


On 12/12/08 11:48, Aurelien Grimaud wrote:
First try, without ngrep or tcpdump.
BYE for CALL-ID=3-18225-127.0.0.1 is retransmitted.
--
Daniel-Constantin Mierla
http://www.asipto.com

Index: modules/tm/t_reply.c
===================================================================
--- modules/tm/t_reply.c        (revision 5326)
+++ modules/tm/t_reply.c        (working copy)
@@ -1030,8 +1030,8 @@
 
        /* reset FR/retransmission timers */
        for (i=t->first_branch; i<t->nr_of_outgoings; i++ )  {
-               reset_timer( &t->uac[i].request.retr_timer );
-               reset_timer( &t->uac[i].request.fr_timer );
+               reset_timer( &t->uac[i].request.retr_timer, TIMER_RB_DEL);
+               reset_timer( &t->uac[i].request.fr_timer, TIMER_RB_DEL);
        }
        LM_DBG("RETR/FR timers reset\n");
 }
@@ -1361,21 +1361,21 @@
        /* it's a cancel which is not e2e ? */
        if ( get_cseq(p_msg)->method_id==METHOD_CANCEL && is_invite(t) ) {
                /* ... then just stop timers */
-               reset_timer( &uac->local_cancel.retr_timer);
+               reset_timer( &uac->local_cancel.retr_timer, TIMER_RB_DEL);
                if ( msg_status >= 200 ) {
-                               reset_timer( &uac->local_cancel.fr_timer);
+                               reset_timer( &uac->local_cancel.fr_timer, 
TIMER_RB_DEL);
                }
                LM_DBG("reply to local CANCEL processed\n");
                goto done;
        }
 
        /* *** stop timers *** */
-       /* stop retransmission */
-       reset_timer(&uac->request.retr_timer);
+       /* stop retransmission and assume end of transaction */
+       reset_timer(&uac->request.retr_timer, TIMER_RB_DEL);
 
        /* stop final response timer only if I got a final response */
        if ( msg_status >= 200 ) {
-               reset_timer( &uac->request.fr_timer);
+               reset_timer( &uac->request.fr_timer, TIMER_RB_DEL);
        }
 
        /* acknowledge negative INVITE replies (do it before detailed
@@ -1468,6 +1468,12 @@
        if (reply_status!=RPS_PROVISIONAL)
                goto done;
        
+       /* not done with current branch, jump to RB Stop state
+        * - we may need to retransmit */
+       reset_timer(&uac->request.retr_timer, TIMER_RB_STOP);
+       if ( msg_status >= 200 )
+               reset_timer( &uac->request.fr_timer, TIMER_RB_STOP);
+
        /* update FR/RETR timers on provisional replies */
        if (msg_status < 200 && (restart_fr_on_each_reply ||
        ((last_uac_status<msg_status) &&
Index: modules/tm/t_funcs.c
===================================================================
--- modules/tm/t_funcs.c        (revision 5326)
+++ modules/tm/t_funcs.c        (working copy)
@@ -123,8 +123,8 @@
 {
        set_kr(REQ_RLSD);
 
-       reset_timer( & trans->uas.response.fr_timer );
-       reset_timer( & trans->uas.response.retr_timer );
+       reset_timer( & trans->uas.response.fr_timer , TIMER_RB_DEL );
+       reset_timer( & trans->uas.response.retr_timer, TIMER_RB_DEL );
 
        cleanup_uac_timers( trans );
        
Index: modules/tm/t_fwd.c
===================================================================
--- modules/tm/t_fwd.c  (revision 5326)
+++ modules/tm/t_fwd.c  (working copy)
@@ -552,8 +552,8 @@
        for (i=t_invite->first_branch; i<t_invite->nr_of_outgoings; i++) {
                if (t_invite->uac[i].last_received==0){
                        /* reset the "request" timers */
-                       reset_timer(&t_invite->uac[i].request.retr_timer);
-                       reset_timer(&t_invite->uac[i].request.fr_timer);
+                       reset_timer(&t_invite->uac[i].request.retr_timer, 
TIMER_RB_DEL);
+                       reset_timer(&t_invite->uac[i].request.fr_timer, 
TIMER_RB_DEL);
                        LOCK_REPLIES( t_invite );
                        if 
(RPS_ERROR==relay_reply(t_invite,FAKED_REPLY,i,487,&dummy_bm))
                                lowest_error = -1; /* force sending 500 error */
@@ -718,6 +718,9 @@
                                        -p_msg->REQ_METHOD);
                        }
 
+                       //LM_DBG("++++++++++++ before sleep\n");
+                       //sleep(2);
+                       //LM_DBG("++++++++++++ after sleep\n");
                        start_retr( &t->uac[i].request );
                        set_kr(REQ_FWDED);
                }
Index: modules/tm/timer.c
===================================================================
--- modules/tm/timer.c  (revision 5326)
+++ modules/tm/timer.c  (working copy)
@@ -302,7 +302,7 @@
                        LM_DBG("retransmission_handler : request resending"
                                " (t=%p, %.9s ... )\n", r_buf->my_T, 
r_buf->buffer.s);
                        if (SEND_BUFFER( r_buf )==-1) {
-                               reset_timer( &r_buf->fr_timer );
+                               reset_timer( &r_buf->fr_timer, TIMER_RB_DEL );
                                fake_reply(r_buf->my_T, r_buf->branch, 503 );
                                return;
                        }
@@ -346,7 +346,7 @@
        }
 #      endif
 
-       reset_timer(  &(r_buf->retr_timer) );
+       reset_timer( &(r_buf->retr_timer) , TIMER_RB_DEL);
 
        /* the transaction is already removed from FR_LIST by the timer */
 
@@ -384,8 +384,8 @@
 {
        int i;
        for (i=0; i<t->nr_of_outgoings; i++ )  {
-               reset_timer(  &t->uac[i].local_cancel.retr_timer );
-               reset_timer(  &t->uac[i].local_cancel.fr_timer );
+               reset_timer(  &t->uac[i].local_cancel.retr_timer, TIMER_RB_DEL);
+               reset_timer(  &t->uac[i].local_cancel.fr_timer , TIMER_RB_DEL);
        }
 }
 
@@ -809,7 +809,7 @@
  *  (successive set_timer won't work unless you're lucky
  *   an catch the race condition, the idea here is there is no
  *   guarantee you can do anything after a timer_reset)*/
-void reset_timer( struct timer_link* tl )
+void reset_timer( struct timer_link* tl , int state)
 {
        /* disqualify this timer from execution by setting its time_out
           to zero; it will stay in timer-list until the timer process
@@ -817,9 +817,10 @@
           but not execute; there is a race condition, though -- see
           timer.c for more details
        */
-       tl->deleted = 1;
+       tl->deleted = state;
+       LM_DBG("+++++++++++  tl=%p, st=%d)\n", tl, state);
 #ifdef EXTRA_DEBUG
-       LM_DBG("(group %d, tl=%p)\n", tl->tg, tl );
+       LM_DBG("(group %d, tl=%p, st=%d)\n", tl->tg, tl, state);
 #endif
 }
 
@@ -848,6 +849,17 @@
                return;
        }
 
+       /* rb timer already scheduled for delete */
+       if(new_tl->deleted==TIMER_RB_DEL)
+       {
+               LM_DBG("++++++++++++ too late to arm the timer [%p] [%d]\n",
+                               new_tl, list_id);
+               return;
+       }
+
+       LM_DBG("++++++++++++ arming the timer [%p] [%d]\n",
+                               new_tl, list_id);
+
        if (!ext_timeout) {
                timeout = timer_id2timeout[ list_id ];
        } else {
Index: modules/tm/timer.h
===================================================================
--- modules/tm/timer.h  (revision 5326)
+++ modules/tm/timer.h  (working copy)
@@ -57,6 +57,9 @@
        NR_OF_TIMER_LISTS
 };
 
+#define TIMER_RB_INIT  0
+#define TIMER_RB_STOP  1
+#define TIMER_RB_DEL   2
 
 /* all you need to put a cell in a timer list
    links to neighbors and timer value */
@@ -67,7 +70,7 @@
        struct timer_link     *ld_tl;
        volatile utime_t      time_out;
        struct timer          *timer_list;
-       unsigned int          deleted;
+       volatile unsigned int deleted;
 #ifdef EXTRA_DEBUG
        enum timer_groups  tg;
 #endif
@@ -106,7 +109,7 @@
 void init_timer_list( enum lists list_id);
 void reset_timer_list( enum lists list_id);
 
-void reset_timer( struct timer_link* tl );
+void reset_timer( struct timer_link* tl, int state);
 
 /* determine timer length and put on a correct timer list */
 void set_timer( struct timer_link *new_tl, enum lists list_id,
_______________________________________________
Users mailing list
Users@lists.kamailio.org
http://lists.kamailio.org/cgi-bin/mailman/listinfo/users

Reply via email to