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,