tm: keep internal retr. intervals in ms
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Thu, 11 Aug 2011 14:58:12 +0000 (16:58 +0200)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Thu, 11 Aug 2011 15:08:16 +0000 (17:08 +0200)
When using ticks to keep the retransmission intervals, any
rounding error (when converting from ms to ticks) is increased
with each doubling of the retransmission interval. In the standard
configuration this means that the last retransmission before t2
kicks in, has an error up to 4 times bigger then the initial one
(the rounding error is max. 1 tick/62.5ms for the initial interval
 => up to 250 ms for the last retransmission before t2).

By keeping the retransmission intervals in ms instead of ticks,
this problem is avoided, and the timing error is always < 1 tick
(62.5 ms) + system timer error (< 10 ms usually).

modules/tm/config.c
modules/tm/config.h
modules/tm/h_table.h
modules/tm/t_funcs.h
modules/tm/t_lookup.c
modules/tm/timer.c
modules/tm/timer.h
modules/tm/tm.c
modules/tm/uac.c

index 8a4e456..a3760fe 100644 (file)
@@ -52,8 +52,8 @@ struct cfg_group_tm   default_tm_cfg = {
        INV_FR_TIME_OUT_NEXT, /* fr_inv_timeout_next */
        WT_TIME_OUT,    /* wait_timeout */
        DEL_TIME_OUT,   /* delete_timeout */
-       RETR_T1,        /* rt_t1_timeout */
-       RETR_T2,        /* rt_t2_timeout */
+       RETR_T1,        /* rt_t1_timeout_ms */
+       RETR_T2,        /* rt_t2_timeout_ms */
 
        /* maximum time an invite or noninv transaction will live, from
         * the moment of creation (overrides larger fr/fr_inv timeouts,
@@ -122,9 +122,9 @@ cfg_def_t   tm_cfg_def[] = {
        {"delete_timer",        CFG_VAR_INT | CFG_ATOMIC,       0, 0, timer_fixup, 0,
                "time after which a to-be-deleted transaction currently "
                "ref-ed by a process will be tried to be deleted again."},
-       {"retr_timer1",         CFG_VAR_INT | CFG_ATOMIC,       0, 0, timer_fixup, 0,
+       {"retr_timer1",         CFG_VAR_INT | CFG_ATOMIC,       0, 0, timer_fixup_ms, 0,
                "initial retransmission period (in milliseconds)"},
-       {"retr_timer2",         CFG_VAR_INT | CFG_ATOMIC,       0, 0, timer_fixup, 0,
+       {"retr_timer2",         CFG_VAR_INT | CFG_ATOMIC,       0, 0, timer_fixup_ms, 0,
                "maximum retransmission period (in milliseconds)"},
        {"max_inv_lifetime",    CFG_VAR_INT | CFG_ATOMIC,       0, 0, timer_fixup, 0,
                "maximum time an invite transaction can live "
index b740ec4..0971bc4 100644 (file)
@@ -109,8 +109,8 @@ struct cfg_group_tm {
        unsigned int    fr_inv_timeout_next;
        unsigned int    wait_timeout;
        unsigned int    delete_timeout;
-       unsigned int    rt_t1_timeout;
-       unsigned int    rt_t2_timeout;
+       unsigned int    rt_t1_timeout_ms;
+       unsigned int    rt_t2_timeout_ms;
        unsigned int    tm_max_inv_lifetime;
        unsigned int    tm_max_noninv_lifetime;
        int     noisy_ctimer;
index c802ab6..df4f979 100644 (file)
@@ -295,9 +295,8 @@ struct totag_elem {
 #      define pass_provisional(_t_)    ((_t_)->flags&T_PASS_PROVISIONAL_FLAG)
 #endif
 
-/* unsigned short should be enough for a retr. timer: max. 65535 ticks =>
- * max  retr. = 1023 s for tick = 15 ms, which should be more then enough and
- * saves us 2*2 bytes */
+/* unsigned short should be enough for a retr. timer: max. 65535 ms =>
+ * max retr. = 65 s which should be enough and saves us 2*2 bytes */
 typedef unsigned short retr_timeout_t;
 
 
@@ -406,8 +405,8 @@ typedef struct cell
        ticks_t fr_timeout;     /* final response interval for retr_bufs */
        ticks_t fr_inv_timeout; /* final inv. response interval for retr_bufs */
 #ifdef TM_DIFF_RT_TIMEOUT
-       retr_timeout_t rt_t1_timeout; /* start retr. interval for retr_bufs */
-       retr_timeout_t rt_t2_timeout; /* maximum retr. interval for retr_bufs */
+       retr_timeout_t rt_t1_timeout_ms; /* start retr. interval for retr_bufs */
+       retr_timeout_t rt_t2_timeout_ms; /* maximum retr. interval for retr_bufs */
 #endif
        ticks_t end_of_life; /* maximum lifetime */
 
index 04ca2d7..1cb3ca7 100644 (file)
@@ -169,19 +169,21 @@ int fr_inv_avp2timer(unsigned int* timer);
 #ifdef TIMER_DEBUG
 #define start_retr(rb) \
        _set_fr_retr((rb), \
-                               ((rb)->dst.proto==PROTO_UDP)?RT_T1_TIMEOUT(rb):(ticks_t)(-1), \
+                               ((rb)->dst.proto==PROTO_UDP) ? RT_T1_TIMEOUT_MS(rb) : \
+                                                                                               (unsigned)(-1), \
                                __FILE__, __FUNCTION__, __LINE__)
 
 #define force_retr(rb) \
-       _set_fr_retr((rb), RT_T1_TIMEOUT(rb), __FILE__, __FUNCTION__, __LINE__)
+       _set_fr_retr((rb), RT_T1_TIMEOUT_MS(rb), __FILE__, __FUNCTION__, __LINE__)
 
 #else
 #define start_retr(rb) \
        _set_fr_retr((rb), \
-                               ((rb)->dst.proto==PROTO_UDP)?RT_T1_TIMEOUT(rb):(ticks_t)(-1))
+                               ((rb)->dst.proto==PROTO_UDP) ? RT_T1_TIMEOUT_MS(rb) : \
+                                                                                               (unsigned)(-1))
 
 #define force_retr(rb) \
-       _set_fr_retr((rb), RT_T1_TIMEOUT(rb))
+       _set_fr_retr((rb), RT_T1_TIMEOUT_MS(rb))
 
 #endif
 
index b626a1f..397d3a5 100644 (file)
@@ -1294,14 +1294,16 @@ static inline void init_new_t(struct cell *new_cell, struct sip_msg *p_msg)
                }
        }
 #ifdef TM_DIFF_RT_TIMEOUT
-       new_cell->rt_t1_timeout=(ticks_t)get_msgid_val(user_rt_t1_timeout,
-                                                                                               p_msg->id, int);
-       if (likely(new_cell->rt_t1_timeout==0))
-               new_cell->rt_t1_timeout=cfg_get(tm, tm_cfg, rt_t1_timeout);
-       new_cell->rt_t2_timeout=(ticks_t)get_msgid_val(user_rt_t2_timeout,
-                                                                                               p_msg->id, int);
-       if (likely(new_cell->rt_t2_timeout==0))
-               new_cell->rt_t2_timeout=cfg_get(tm, tm_cfg, rt_t2_timeout);
+       new_cell->rt_t1_timeout_ms = (retr_timeout_t) get_msgid_val(
+                                                                                                               user_rt_t1_timeout_ms,
+                                                                                                               p_msg->id, int);
+       if (likely(new_cell->rt_t1_timeout_ms == 0))
+               new_cell->rt_t1_timeout_ms = cfg_get(tm, tm_cfg, rt_t1_timeout_ms);
+       new_cell->rt_t2_timeout_ms = (retr_timeout_t) get_msgid_val(
+                                                                                                               user_rt_t2_timeout_ms,
+                                                                                                               p_msg->id, int);
+       if (likely(new_cell->rt_t2_timeout_ms == 0))
+               new_cell->rt_t2_timeout_ms = cfg_get(tm, tm_cfg, rt_t2_timeout_ms);
 #endif
        new_cell->on_branch=get_on_branch();
 }
@@ -1813,30 +1815,30 @@ int t_reset_fr()
 
 /* params: retr. t1 & retr. t2 value in ms, 0 means "do not touch"
  * ret: 1 on success, -1 on error (script safe)*/
-int t_set_retr(struct sip_msg* msg, unsigned int t1_to, unsigned int t2_to)
+int t_set_retr(struct sip_msg* msg, unsigned int t1_ms, unsigned int t2_ms)
 {
        struct cell *t;
        ticks_t retr_t1, retr_t2;
        
        
-       retr_t1=MS_TO_TICKS((ticks_t)t1_to);
-       if (unlikely((retr_t1==0) && (t1_to!=0))){
-               ERR("t_set_retr: retr. t1 interval too small (%u)\n", t1_to);
+       retr_t1=MS_TO_TICKS((ticks_t)t1_ms);
+       if (unlikely((retr_t1==0) && (t1_ms!=0))){
+               ERR("t_set_retr: retr. t1 interval too small (%u)\n", t1_ms);
                return -1;
        }
-       if (unlikely(MAX_UVAR_VALUE(t->rt_t1_timeout) < retr_t1)){
+       if (unlikely(MAX_UVAR_VALUE(t->rt_t1_timeout_ms) < t1_ms)){
                ERR("t_set_retr: retr. t1 interval too big: %d (max %lu)\n",
-                               t1_to, TICKS_TO_MS(MAX_UVAR_VALUE(t->rt_t1_timeout))); 
+                               t1_ms, MAX_UVAR_VALUE(t->rt_t1_timeout_ms)); 
                return -1;
        } 
-       retr_t2=MS_TO_TICKS((ticks_t)t2_to);
-       if (unlikely((retr_t2==0) && (t2_to!=0))){
-               ERR("t_set_retr: retr. t2 interval too small (%d)\n", t2_to);
+       retr_t2=MS_TO_TICKS((ticks_t)t2_ms);
+       if (unlikely((retr_t2==0) && (t2_ms!=0))){
+               ERR("t_set_retr: retr. t2 interval too small (%d)\n", t2_ms);
                return -1;
        }
-       if (unlikely(MAX_UVAR_VALUE(t->rt_t2_timeout) < retr_t2)){
+       if (unlikely(MAX_UVAR_VALUE(t->rt_t2_timeout_ms) < t2_ms)){
                ERR("t_set_retr: retr. t2 interval too big: %u (max %lu)\n",
-                               t2_to, TICKS_TO_MS(MAX_UVAR_VALUE(t->rt_t2_timeout))); 
+                               t2_ms, MAX_UVAR_VALUE(t->rt_t2_timeout_ms)); 
                return -1;
        } 
        
@@ -1845,10 +1847,10 @@ int t_set_retr(struct sip_msg* msg, unsigned int t1_to, unsigned int t2_to)
         * in REQUEST_ROUTE T will be set only if the transaction was already
         * created; if not -> use the static variables */
        if (!t || t==T_UNDEFINED ){
-               set_msgid_val(user_rt_t1_timeout, msg->id, int, (int)retr_t1);
-               set_msgid_val(user_rt_t2_timeout, msg->id, int, (int)retr_t2);
+               set_msgid_val(user_rt_t1_timeout_ms, msg->id, int, (int)t1_ms);
+               set_msgid_val(user_rt_t2_timeout_ms, msg->id, int, (int)t2_ms);
        }else{
-               change_retr(t, 1, retr_t1, retr_t2); /* change running uac timers */
+               change_retr(t, 1, t1_ms, t2_ms); /* change running uac timers */
        }
        return 1;
 }
@@ -1863,13 +1865,14 @@ int t_reset_retr()
         * in REQUEST_ROUTE T will be set only if the transaction was already
         * created; if not -> use the static variables */
        if (!t || t==T_UNDEFINED ){
-               memset(&user_rt_t1_timeout, 0, sizeof(user_rt_t1_timeout));
-               memset(&user_rt_t2_timeout, 0, sizeof(user_rt_t2_timeout));
+               memset(&user_rt_t1_timeout_ms, 0, sizeof(user_rt_t1_timeout_ms));
+               memset(&user_rt_t2_timeout_ms, 0, sizeof(user_rt_t2_timeout_ms));
        }else{
+                /* change running uac timers */
                change_retr(t,
                        1,
-                       cfg_get(tm, tm_cfg, rt_t1_timeout),
-                       cfg_get(tm, tm_cfg, rt_t2_timeout)); /* change running uac timers */
+                       cfg_get(tm, tm_cfg, rt_t1_timeout_ms),
+                       cfg_get(tm, tm_cfg, rt_t2_timeout_ms));
        }
        return 1;
 }
index 349d6a8..b834f11 100644 (file)
 struct msgid_var user_fr_timeout;
 struct msgid_var user_fr_inv_timeout;
 #ifdef TM_DIFF_RT_TIMEOUT
-struct msgid_var user_rt_t1_timeout;
-struct msgid_var user_rt_t2_timeout;
+struct msgid_var user_rt_t1_timeout_ms;
+struct msgid_var user_rt_t2_timeout_ms;
 #endif
 struct msgid_var user_inv_max_lifetime;
 struct msgid_var user_noninv_max_lifetime;
@@ -185,8 +185,6 @@ int tm_init_timers(void)
        default_tm_cfg.fr_inv_timeout=MS_TO_TICKS(default_tm_cfg.fr_inv_timeout);
        default_tm_cfg.wait_timeout=MS_TO_TICKS(default_tm_cfg.wait_timeout);
        default_tm_cfg.delete_timeout=MS_TO_TICKS(default_tm_cfg.delete_timeout);
-       default_tm_cfg.rt_t1_timeout=MS_TO_TICKS(default_tm_cfg.rt_t1_timeout);
-       default_tm_cfg.rt_t2_timeout=MS_TO_TICKS(default_tm_cfg.rt_t2_timeout);
        default_tm_cfg.tm_max_inv_lifetime=MS_TO_TICKS(default_tm_cfg.tm_max_inv_lifetime);
        default_tm_cfg.tm_max_noninv_lifetime=MS_TO_TICKS(default_tm_cfg.tm_max_noninv_lifetime);
        /* fix 0 values to 1 tick (minimum possible wait time ) */
@@ -194,8 +192,8 @@ int tm_init_timers(void)
        if (default_tm_cfg.fr_inv_timeout==0) default_tm_cfg.fr_inv_timeout=1;
        if (default_tm_cfg.wait_timeout==0) default_tm_cfg.wait_timeout=1;
        if (default_tm_cfg.delete_timeout==0) default_tm_cfg.delete_timeout=1;
-       if (default_tm_cfg.rt_t2_timeout==0) default_tm_cfg.rt_t2_timeout=1;
-       if (default_tm_cfg.rt_t1_timeout==0) default_tm_cfg.rt_t1_timeout=1;
+       if (default_tm_cfg.rt_t2_timeout_ms==0) default_tm_cfg.rt_t2_timeout_ms=1;
+       if (default_tm_cfg.rt_t1_timeout_ms==0) default_tm_cfg.rt_t1_timeout_ms=1;
        if (default_tm_cfg.tm_max_inv_lifetime==0) default_tm_cfg.tm_max_inv_lifetime=1;
        if (default_tm_cfg.tm_max_noninv_lifetime==0) default_tm_cfg.tm_max_noninv_lifetime=1;
        
@@ -203,8 +201,10 @@ int tm_init_timers(void)
        SIZE_FIT_CHECK(fr_timeout, default_tm_cfg.fr_timeout, "fr_timer");
        SIZE_FIT_CHECK(fr_inv_timeout, default_tm_cfg.fr_inv_timeout, "fr_inv_timer");
 #ifdef TM_DIFF_RT_TIMEOUT
-       SIZE_FIT_CHECK(rt_t1_timeout, default_tm_cfg.rt_t1_timeout, "retr_timer1");
-       SIZE_FIT_CHECK(rt_t2_timeout, default_tm_cfg.rt_t2_timeout, "retr_timer2");
+       SIZE_FIT_CHECK(rt_t1_timeout_ms, default_tm_cfg.rt_t1_timeout_ms,
+                                       "retr_timer1");
+       SIZE_FIT_CHECK(rt_t2_timeout_ms, default_tm_cfg.rt_t2_timeout_ms,
+                                       "retr_timer2");
 #endif
        SIZE_FIT_CHECK(end_of_life, default_tm_cfg.tm_max_inv_lifetime, "max_inv_lifetime");
        SIZE_FIT_CHECK(end_of_life, default_tm_cfg.tm_max_noninv_lifetime, "max_noninv_lifetime");
@@ -212,8 +212,8 @@ int tm_init_timers(void)
        memset(&user_fr_timeout, 0, sizeof(user_fr_timeout));
        memset(&user_fr_inv_timeout, 0, sizeof(user_fr_inv_timeout));
 #ifdef TM_DIFF_RT_TIMEOUT
-       memset(&user_rt_t1_timeout, 0, sizeof(user_rt_t1_timeout));
-       memset(&user_rt_t2_timeout, 0, sizeof(user_rt_t2_timeout));
+       memset(&user_rt_t1_timeout_ms, 0, sizeof(user_rt_t1_timeout_ms));
+       memset(&user_rt_t2_timeout_ms, 0, sizeof(user_rt_t2_timeout_ms));
 #endif
        memset(&user_inv_max_lifetime, 0, sizeof(user_inv_max_lifetime));
        memset(&user_noninv_max_lifetime, 0, sizeof(user_noninv_max_lifetime));
@@ -222,7 +222,7 @@ int tm_init_timers(void)
                        " max_inv_lifetime=%d max_noninv_lifetime=%d\n",
                        default_tm_cfg.fr_timeout, default_tm_cfg.fr_inv_timeout,
                        default_tm_cfg.wait_timeout, default_tm_cfg.delete_timeout,
-                       default_tm_cfg.rt_t1_timeout, default_tm_cfg.rt_t2_timeout,
+                       default_tm_cfg.rt_t1_timeout_ms, default_tm_cfg.rt_t2_timeout_ms,
                        default_tm_cfg.tm_max_inv_lifetime, default_tm_cfg.tm_max_noninv_lifetime);
        return 0;
 error:
@@ -263,10 +263,6 @@ int timer_fixup(void *handle, str *gname, str *name, void **val)
        /* size fix checks */
        IF_IS_TIMER_NAME(fr_timeout, "fr_timer")
        else IF_IS_TIMER_NAME(fr_inv_timeout, "fr_inv_timer")
-#ifdef TM_DIFF_RT_TIMEOUT
-       else IF_IS_TIMER_NAME(rt_t1_timeout, "retr_timer1")
-       else IF_IS_TIMER_NAME(rt_t2_timeout, "retr_timer2")
-#endif
        else IF_IS_TIMER_NAME(end_of_life, "max_inv_lifetime")
        else IF_IS_TIMER_NAME(end_of_life, "max_noninv_lifetime")
 
@@ -277,6 +273,30 @@ error:
        return -1;
 }
 
+
+
+/** fixup function for timer values that are kept in ms.
+ * (called by the configuration framework)
+ * It checks if the value fits in the tm structures 
+ */
+int timer_fixup_ms(void *handle, str *gname, str *name, void **val)
+{
+       long    t;
+
+       t = (long)(*val);
+
+       /* size fix checks */
+#ifdef TM_DIFF_RT_TIMEOUT
+       IF_IS_TIMER_NAME(rt_t1_timeout_ms, "retr_timer1")
+       else IF_IS_TIMER_NAME(rt_t2_timeout_ms, "retr_timer2")
+#endif
+
+       return 0;
+
+error:
+       return -1;
+}
+
 /******************** handlers ***************************/
 
 
@@ -528,7 +548,8 @@ ticks_t retr_buf_handler(ticks_t ticks, struct timer_ln* tl, void *p)
        ticks_t fr_remainder;
        ticks_t retr_remainder;
        ticks_t retr_interval;
-       ticks_t new_retr_interval;
+       unsigned long new_retr_interval_ms;
+       unsigned long crt_retr_interval_ms;
        struct cell *t;
 
        rbuf=(struct  retr_buf*)
@@ -569,28 +590,20 @@ ticks_t retr_buf_handler(ticks_t ticks, struct timer_ln* tl, void *p)
                        if ((s_ticks_t)(rbuf->retr_expire-ticks)<=0){
                                if (rbuf->flags & F_RB_RETR_DISABLED)
                                        goto disabled;
-                               /* retr_interval= min (2*ri, rt_t2) , *p==2*ri*/
-                               /* no branch version: 
-                                       #idef CC_SIGNED_RIGHT_SHIFT
-                                               ri=  rt_t2+((2*ri-rt_t2) & 
-                                               ((signed)(2*ri-rt_t2)>>(sizeof(ticks_t)*8-1));
-                                       #else
-                                               ri=rt_t2+((2*ri-rt_t2)& -(2*ri<rt_t2));
-                                       #endif
-                               */
-                               
+                               crt_retr_interval_ms = (unsigned long)p;
                                /* get the  current interval from timer param. */
-                               if ((rbuf->flags & F_RB_T2) || 
-                                               (((ticks_t)(unsigned long)p)>RT_T2_TIMEOUT(rbuf))){
-                                       retr_interval=RT_T2_TIMEOUT(rbuf);
-                                       new_retr_interval=RT_T2_TIMEOUT(rbuf);
+                               if (unlikely((rbuf->flags & F_RB_T2) ||
+                                               (crt_retr_interval_ms > RT_T2_TIMEOUT_MS(rbuf)))){
+                                       retr_interval = MS_TO_TICKS(RT_T2_TIMEOUT_MS(rbuf));
+                                       new_retr_interval_ms = RT_T2_TIMEOUT_MS(rbuf);
                                }else{
-                                       retr_interval=(ticks_t)(unsigned long)p;
-                                       new_retr_interval=retr_interval<<1;
+                                       retr_interval = MS_TO_TICKS(crt_retr_interval_ms);
+                                       new_retr_interval_ms=crt_retr_interval_ms<<1;
                                }
 #ifdef TIMER_DEBUG
-                               DBG("tm: timer: retr: new interval %d (max %d)\n", 
-                                               retr_interval, RT_T2_TIMEOUT(rbuf));
+                               DBG("tm: timer: retr: new interval %ld ms / %d ticks"
+                                               " (max %d ms)\n", new_retr_interval_ms, retr_interval,
+                                               RT_T2_TIMEOUT_MS(rbuf));
 #endif
                                /* we could race with the reply_received code, but the 
                                 * worst thing that can happen is to delay a reset_to_t2
@@ -598,9 +611,9 @@ ticks_t retr_buf_handler(ticks_t ticks, struct timer_ln* tl, void *p)
                                rbuf->retr_expire=ticks+retr_interval;
                                /* set new interval to -1 on error, or retr_int. on success */
                                retr_remainder=retransmission_handler(rbuf) | retr_interval;
-                               /* store the next retr. interval inside the timer struct,
+                               /* store the next retr. interval in ms inside the timer struct,
                                 * in the data member */
-                               tl->data=(void*)(unsigned long)(new_retr_interval);
+                               tl->data=(void*)(new_retr_interval_ms);
                        }else{
                                retr_remainder= rbuf->retr_expire-ticks;
                                DBG("tm: timer: retr: nothing to do, expire in %d\n", 
index e7847d3..0d782c0 100644 (file)
 
 
 #ifdef  TM_DIFF_RT_TIMEOUT
-#define RT_T1_TIMEOUT(rb)      ((rb)->my_T->rt_t1_timeout)
-#define RT_T2_TIMEOUT(rb)      ((rb)->my_T->rt_t2_timeout)
+#define RT_T1_TIMEOUT_MS(rb)   ((rb)->my_T->rt_t1_timeout_ms)
+#define RT_T2_TIMEOUT_MS(rb)   ((rb)->my_T->rt_t2_timeout_ms)
 #else
-#define RT_T1_TIMEOUT(rb)      (cfg_get(tm, tm_cfg, rt_t1_timeout))
-#define RT_T2_TIMEOUT(rb)      (cfg_get(tm, tm_cfg, rt_t2_timeout))
+#define RT_T1_TIMEOUT_MS(rb)   (cfg_get(tm, tm_cfg, rt_t1_timeout_ms))
+#define RT_T2_TIMEOUT_MS(rb)   (cfg_get(tm, tm_cfg, rt_t2_timeout_ms))
 #endif
 
 #define TM_REQ_TIMEOUT(t) \
 extern struct msgid_var user_fr_timeout;
 extern struct msgid_var user_fr_inv_timeout;
 #ifdef TM_DIFF_RT_TIMEOUT
-extern struct msgid_var user_rt_t1_timeout;
-extern struct msgid_var user_rt_t2_timeout;
+extern struct msgid_var user_rt_t1_timeout_ms;
+extern struct msgid_var user_rt_t2_timeout_ms;
 #endif
 extern struct msgid_var user_inv_max_lifetime;
 extern struct msgid_var user_noninv_max_lifetime;
@@ -166,6 +166,7 @@ extern int tm_init_timers(void);
  * \return 0 on success, -1 on error
  */
 int timer_fixup(void *handle, str *gname, str *name, void **val);
+int timer_fixup_ms(void *handle, str *gname, str *name, void **val);
 
 ticks_t wait_handler(ticks_t t, struct timer_ln *tl, void* data);
 ticks_t retr_buf_handler(ticks_t t, struct timer_ln *tl, void* data);
@@ -176,7 +177,7 @@ ticks_t retr_buf_handler(ticks_t t, struct timer_ln *tl, void* data);
 
 #define init_rb_timers(rb) \
        timer_init(&(rb)->timer, retr_buf_handler, \
-                               (void*)(unsigned long)RT_T1_TIMEOUT(rb), 0)
+                               (void*)(unsigned long)(RT_T1_TIMEOUT_MS(rb)), 0)
 
 /* set fr & retr timer
  * rb  -  pointer to struct retr_buf
@@ -184,23 +185,26 @@ ticks_t retr_buf_handler(ticks_t t, struct timer_ln *tl, void* data);
  * returns: -1 on error, 0 on success
  */
 #ifdef TIMER_DEBUG
-inline static int _set_fr_retr(struct retr_buf* rb, ticks_t retr,
+inline static int _set_fr_retr(struct retr_buf* rb, unsigned retr_ms,
                                                                const char* file, const char* func,
                                                                unsigned line)
 #else
-inline static int _set_fr_retr(struct retr_buf* rb, ticks_t retr)
+inline static int _set_fr_retr(struct retr_buf* rb, unsigned retr_ms)
 #endif
 {
        ticks_t timeout;
        ticks_t ticks;
        ticks_t eol;
+       ticks_t retr_ticks;
        int ret;
        
        ticks=get_ticks_raw();
        timeout=rb->my_T->fr_timeout;
        eol=rb->my_T->end_of_life;
-       rb->timer.data=(void*)(unsigned long)(2*retr); /* hack , next retr. int. */
-       rb->retr_expire=ticks+retr;
+       /* hack , next retr. int. */
+       retr_ticks = MS_TO_TICKS(retr_ms);
+       rb->timer.data=(void*)(unsigned long)(2*retr_ms);
+       rb->retr_expire=ticks + retr_ticks;
        if (unlikely(rb->t_active)){
                /* we could have set_fr_retr called in the same time (acceptable 
                 * race), we rely on timer_add adding it only once */
@@ -211,11 +215,11 @@ inline static int _set_fr_retr(struct retr_buf* rb, ticks_t retr)
                LOG(L_CRIT, "WARNING: -_set_fr_timer- already added: %p , tl=%p!!!\n",
                                        rb, &rb->timer);
        }
-       /* set active & if retr==-1 set disabled */
-       rb->flags|= (F_RB_RETR_DISABLED & -(retr==-1)); 
+       /* set active & if retr_ms==-1 set disabled */
+       rb->flags|= (F_RB_RETR_DISABLED & -(retr_ms==(unsigned)-1));
 #ifdef TM_FAST_RETR_TIMER
-       /* set timer to fast if retr enabled (retr!=-1) */
-       rb->timer.flags|=(F_TIMER_FAST & -(retr!=-1));
+       /* set timer to fast if retr enabled (retr_ms!=-1) */
+       rb->timer.flags|=(F_TIMER_FAST & -(retr_ms!=(unsigned)-1));
 #endif
        /* adjust timeout to MIN(fr, maximum lifetime) if rb is a request
         *  (for neg. replies we are force to wait for the ACK so use fr) */
@@ -232,10 +236,10 @@ inline static int _set_fr_retr(struct retr_buf* rb, ticks_t retr)
                return 0;
        }
 #ifdef TIMER_DEBUG
-       ret=timer_add_safe(&(rb)->timer, (timeout<retr)?timeout:retr,
+       ret=timer_add_safe(&(rb)->timer, (timeout<retr_ticks)?timeout:retr_ticks,
                                                        file, func, line);
 #else
-       ret=timer_add(&(rb)->timer, (timeout<retr)?timeout:retr);
+       ret=timer_add(&(rb)->timer, (timeout<retr_ticks)?timeout:retr_ticks);
 #endif
        if (ret==0) rb->t_active=1;
        membar_write_atomic_op(); /* make sure t_active will be commited to mem.
@@ -265,7 +269,7 @@ do{ \
 #define switch_rb_retr_to_t2(rb) \
        do{ \
                (rb)->flags|=F_RB_T2; \
-               (rb)->retr_expire=get_ticks_raw()+RT_T2_TIMEOUT(rb); \
+               (rb)->retr_expire=get_ticks_raw()+MS_TO_TICKS(RT_T2_TIMEOUT_MS(rb)); \
        }while(0)
 
 
@@ -324,23 +328,23 @@ inline static void change_fr(struct cell* t, ticks_t fr_inv, ticks_t fr)
  *  if timer value==0 => leave it unchanged
  */
 inline static void change_retr(struct cell* t, int now,
-                                                               ticks_t rt_t1, ticks_t rt_t2)
+                                                               unsigned rt_t1_ms, unsigned rt_t2_ms)
 {
        int i;
 
-       if (rt_t1) t->rt_t1_timeout=rt_t1;
-       if (rt_t2) t->rt_t2_timeout=rt_t2;
+       if (rt_t1_ms) t->rt_t1_timeout_ms=rt_t1_ms;
+       if (rt_t2_ms) t->rt_t2_timeout_ms=rt_t2_ms;
        if (now){
                for (i=0; i<t->nr_of_outgoings; i++){
-                       if (t->uac[i].request.t_active){ 
-                                       if ((t->uac[i].request.flags & F_RB_T2) && rt_t2)
+                       if (t->uac[i].request.t_active){
+                                       if ((t->uac[i].request.flags & F_RB_T2) && rt_t2_ms)
                                                /* not really needed (?) - if F_RB_T2 is set
                                                 * t->rt_t2_timeout will be used anyway */
-                                               t->uac[i].request.timer.data=
-                                                                       (void*)(unsigned long)rt_t2;
-                                       else if (rt_t1)
-                                               t->uac[i].request.timer.data=
-                                                                       (void*)(unsigned long)rt_t1;
+                                               t->uac[i].request.timer.data =
+                                                       (void*)(unsigned long)rt_t2_ms;
+                                       else if (rt_t1_ms)
+                                               t->uac[i].request.timer.data =
+                                                       (void*)(unsigned long)rt_t1_ms;
                        }
                }
        }
index 3fda145..d9b8bbf 100644 (file)
@@ -482,8 +482,8 @@ static param_export_t params[]={
        {"fr_inv_timer",        PARAM_INT, &default_tm_cfg.fr_inv_timeout        },
        {"wt_timer",            PARAM_INT, &default_tm_cfg.wait_timeout          },
        {"delete_timer",        PARAM_INT, &default_tm_cfg.delete_timeout        },
-       {"retr_timer1",         PARAM_INT, &default_tm_cfg.rt_t1_timeout         },
-       {"retr_timer2"  ,       PARAM_INT, &default_tm_cfg.rt_t2_timeout         },
+       {"retr_timer1",         PARAM_INT, &default_tm_cfg.rt_t1_timeout_ms      },
+       {"retr_timer2"  ,       PARAM_INT, &default_tm_cfg.rt_t2_timeout_ms      },
        {"max_inv_lifetime",    PARAM_INT, &default_tm_cfg.tm_max_inv_lifetime   },
        {"max_noninv_lifetime", PARAM_INT, &default_tm_cfg.tm_max_noninv_lifetime},
        {"noisy_ctimer",        PARAM_INT, &default_tm_cfg.noisy_ctimer          },
index c552f5a..bbf9d7c 100644 (file)
@@ -304,8 +304,8 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
        new_cell->end_of_life=get_ticks_raw()+lifetime;
 #ifdef TM_DIFF_RT_TIMEOUT
        /* same as above for retransmission intervals */
-       new_cell->rt_t1_timeout=cfg_get(tm, tm_cfg, rt_t1_timeout);
-       new_cell->rt_t2_timeout=cfg_get(tm, tm_cfg, rt_t2_timeout);
+       new_cell->rt_t1_timeout_ms = cfg_get(tm, tm_cfg, rt_t1_timeout_ms);
+       new_cell->rt_t2_timeout_ms = cfg_get(tm, tm_cfg, rt_t2_timeout_ms);
 #endif
 
        set_kr(REQ_FWDED);