tm: keep internal retr. intervals in ms
[sip-router] / modules / tm / timer.c
1 /*
2  * Copyright (C) 2001-2003 FhG Fokus
3  *
4  * This file is part of ser, a free SIP server.
5  *
6  * ser is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  * For a license to use the ser software under conditions
12  * other than those described here, or to purchase support for this
13  * software, please contact iptel.org by e-mail at the following addresses:
14  *    info@iptel.org
15  *
16  * ser is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License 
22  * along with this program; if not, write to the Free Software 
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25
26 /*
27  * History:
28  * --------
29  *  2003-06-27  timers are not unlinked if timerlist is 0 (andrei)
30  *  2004-02-13  t->is_invite, t->local, t->noisy_ctimer replaced;
31  *              timer_link.payload removed (bogdan)
32  *  2005-10-03  almost completely rewritten to use the new timers (andrei)
33  *  2005-12-12  on final response marked the rb as removed to avoid deleting
34  *              it from the timer handle; timer_allow_del()  (andrei)
35  *  2006-08-11  final_response_handler dns failover support for timeout-ed
36  *              invites (andrei)
37  *  2006-09-28  removed the 480 on fr_inv_timeout reply: on timeout always 
38  *               return a 408
39  *              set the corresponding "faked" failure route sip_msg->msg_flags 
40  *               on timeout or if the branch received a reply (andrei)
41  *  2007-03-15  TMCB_ONSEND callbacks support (andrei)
42  *  2007-05-29  delete on transaction ref_count==0 : removed the delete timer
43  *               (andrei)
44  * 2007-06-01  support for different retransmissions intervals per transaction;
45  *             added maximum inv. and non-inv. transaction life time (andrei)
46  */
47
48 /**
49  * \file
50  * \brief TM :: timer support
51  * 
52  * TM timer support. It has been designed for high performance using
53  * some techniques of which timer users need to be aware.
54  * - One technique is "fixed-timer-length". We maintain separate 
55  * timer lists, all of them include elements of the same time
56  * to fire. That allows *appending* new events to the list as
57  * opposed to inserting them by time, which is costly due to
58  * searching time spent in a mutex. The performance benefit is
59  * noticeable. The limitation is you need a new timer list for
60  * each new timer length.
61  * - Another technique is the timer process slices off expired elements
62  * from the list in a mutex, but executes the timer after the mutex
63  * is left. That saves time greatly as whichever process wants to
64  * add/remove a timer, it does not have to wait until the current
65  * list is processed. However, be aware the timers may hit in a delayed
66  * manner; you have no guarantee in your process that after resetting a timer, 
67  * it will no more hit. It might have been removed by timer process,
68  * and is waiting to be executed.
69  * 
70  * The following example shows it:
71  * 
72  *              PROCESS1                                TIMER PROCESS
73  * 
74  * -    0.                                              timer hits, it is removed from queue and
75  *                                                      about to be executed
76  * -    1.      process1 decides to
77  *              reset the timer 
78  * -    2.                                              timer is executed now
79  * -    3.      if the process1 naively
80  *              thinks the timer could not 
81  *              have been executed after 
82  *              resetting the timer, it is
83  *              WRONG -- it was (step 2.)
84  * 
85  * So be careful when writing the timer handlers. Currently defined timers 
86  * don't hurt if they hit delayed, I hope at least. Retransmission timer 
87  * may results in a useless retransmission -- not too bad. FR timer not too
88  * bad either as timer processing uses a REPLY mutex making it safe to other
89  * processing affecting transaction state. Wait timer not bad either -- processes
90  * putting a transaction on wait don't do anything with it anymore.
91  * 
92  *      Example when it does not hurt:
93  * 
94  *              PROCESS1                                TIMER PROCESS
95  * 
96  * -    0.                                              RETR timer removed from list and
97  *                                                      scheduled for execution
98  * -    1. 200/BYE received->
99  *         reset RETR, put_on_wait
100  * -    2.                                              RETR timer executed -- too late but it does
101  *                                                      not hurt
102  * -    3.                                              WAIT handler executed
103  *
104  * The rule of thumb is don't touch data you put under a timer. Create data,
105  * put them under a timer, and let them live until they are safely destroyed from
106  * wait/delete timer.  The only safe place to manipulate the data is 
107  * from timer process in which delayed timers cannot hit (all timers are
108  * processed sequentially).
109  * 
110  * A "bad example" -- rewriting content of retransmission buffer
111  * in an unprotected way is bad because a delayed retransmission timer might 
112  * hit. Thats why our reply retransmission procedure is enclosed in 
113  * a REPLY_LOCK.
114  * \ingroup tm
115  */
116
117
118 #include "defs.h"
119
120
121 #include "config.h"
122 #include "h_table.h"
123 #include "timer.h"
124 #include "../../dprint.h"
125 #include "lock.h"
126 #include "t_stats.h"
127
128 #include "../../hash_func.h"
129 #include "../../dprint.h"
130 #include "../../config.h"
131 #include "../../parser/parser_f.h"
132 #include "../../ut.h"
133 #include "../../timer_ticks.h"
134 #include "../../compiler_opt.h" 
135 #include "../../sr_compat.h" 
136 #include "t_funcs.h"
137 #include "t_reply.h"
138 #include "t_cancel.h"
139 #include "t_hooks.h"
140 #ifdef USE_DNS_FAILOVER
141 #include "t_fwd.h" /* t_send_branch */
142 #include "../../cfg_core.h" /* cfg_get(core, core_cfg, use_dns_failover) */
143 #endif
144 #ifdef USE_DST_BLACKLIST
145 #include "../../dst_blacklist.h"
146 #endif
147
148
149
150 struct msgid_var user_fr_timeout;
151 struct msgid_var user_fr_inv_timeout;
152 #ifdef TM_DIFF_RT_TIMEOUT
153 struct msgid_var user_rt_t1_timeout_ms;
154 struct msgid_var user_rt_t2_timeout_ms;
155 #endif
156 struct msgid_var user_inv_max_lifetime;
157 struct msgid_var user_noninv_max_lifetime;
158
159
160 /**
161  * \brief Check helper for configuration framework values
162  * 
163  * Check helper for configuration framework values for internal use
164  * The val should be unsigned or positive, use
165  * <= instead of < to get read of gcc warning when 
166  * sizeof(cell_member)==sizeof(val) (Note that this limits
167  * maximum value to max. type -1)
168  */
169 #define SIZE_FIT_CHECK(cell_member, val, cfg_name) \
170         if (MAX_UVAR_VALUE(((struct cell*)0)->cell_member) <= (val)){ \
171                 ERR("tm_init_timers: " cfg_name " too big: %lu (%lu ticks) " \
172                                 "- max %lu (%lu ticks) \n", TICKS_TO_MS((unsigned long)(val)),\
173                                 (unsigned long)(val), \
174                                 TICKS_TO_MS(MAX_UVAR_VALUE(((struct cell*)0)->cell_member)), \
175                                 MAX_UVAR_VALUE(((struct cell*)0)->cell_member)); \
176                 goto error; \
177         } 
178
179 /**
180  * \brief fix timer values to ticks
181  */
182 int tm_init_timers(void)
183 {
184         default_tm_cfg.fr_timeout=MS_TO_TICKS(default_tm_cfg.fr_timeout); 
185         default_tm_cfg.fr_inv_timeout=MS_TO_TICKS(default_tm_cfg.fr_inv_timeout);
186         default_tm_cfg.wait_timeout=MS_TO_TICKS(default_tm_cfg.wait_timeout);
187         default_tm_cfg.delete_timeout=MS_TO_TICKS(default_tm_cfg.delete_timeout);
188         default_tm_cfg.tm_max_inv_lifetime=MS_TO_TICKS(default_tm_cfg.tm_max_inv_lifetime);
189         default_tm_cfg.tm_max_noninv_lifetime=MS_TO_TICKS(default_tm_cfg.tm_max_noninv_lifetime);
190         /* fix 0 values to 1 tick (minimum possible wait time ) */
191         if (default_tm_cfg.fr_timeout==0) default_tm_cfg.fr_timeout=1;
192         if (default_tm_cfg.fr_inv_timeout==0) default_tm_cfg.fr_inv_timeout=1;
193         if (default_tm_cfg.wait_timeout==0) default_tm_cfg.wait_timeout=1;
194         if (default_tm_cfg.delete_timeout==0) default_tm_cfg.delete_timeout=1;
195         if (default_tm_cfg.rt_t2_timeout_ms==0) default_tm_cfg.rt_t2_timeout_ms=1;
196         if (default_tm_cfg.rt_t1_timeout_ms==0) default_tm_cfg.rt_t1_timeout_ms=1;
197         if (default_tm_cfg.tm_max_inv_lifetime==0) default_tm_cfg.tm_max_inv_lifetime=1;
198         if (default_tm_cfg.tm_max_noninv_lifetime==0) default_tm_cfg.tm_max_noninv_lifetime=1;
199         
200         /* size fit checks */
201         SIZE_FIT_CHECK(fr_timeout, default_tm_cfg.fr_timeout, "fr_timer");
202         SIZE_FIT_CHECK(fr_inv_timeout, default_tm_cfg.fr_inv_timeout, "fr_inv_timer");
203 #ifdef TM_DIFF_RT_TIMEOUT
204         SIZE_FIT_CHECK(rt_t1_timeout_ms, default_tm_cfg.rt_t1_timeout_ms,
205                                         "retr_timer1");
206         SIZE_FIT_CHECK(rt_t2_timeout_ms, default_tm_cfg.rt_t2_timeout_ms,
207                                         "retr_timer2");
208 #endif
209         SIZE_FIT_CHECK(end_of_life, default_tm_cfg.tm_max_inv_lifetime, "max_inv_lifetime");
210         SIZE_FIT_CHECK(end_of_life, default_tm_cfg.tm_max_noninv_lifetime, "max_noninv_lifetime");
211         
212         memset(&user_fr_timeout, 0, sizeof(user_fr_timeout));
213         memset(&user_fr_inv_timeout, 0, sizeof(user_fr_inv_timeout));
214 #ifdef TM_DIFF_RT_TIMEOUT
215         memset(&user_rt_t1_timeout_ms, 0, sizeof(user_rt_t1_timeout_ms));
216         memset(&user_rt_t2_timeout_ms, 0, sizeof(user_rt_t2_timeout_ms));
217 #endif
218         memset(&user_inv_max_lifetime, 0, sizeof(user_inv_max_lifetime));
219         memset(&user_noninv_max_lifetime, 0, sizeof(user_noninv_max_lifetime));
220         
221         DBG("tm: tm_init_timers: fr=%d fr_inv=%d wait=%d delete=%d t1=%d t2=%d"
222                         " max_inv_lifetime=%d max_noninv_lifetime=%d\n",
223                         default_tm_cfg.fr_timeout, default_tm_cfg.fr_inv_timeout,
224                         default_tm_cfg.wait_timeout, default_tm_cfg.delete_timeout,
225                         default_tm_cfg.rt_t1_timeout_ms, default_tm_cfg.rt_t2_timeout_ms,
226                         default_tm_cfg.tm_max_inv_lifetime, default_tm_cfg.tm_max_noninv_lifetime);
227         return 0;
228 error:
229         return -1;
230 }
231
232 /**
233  * \brief Internal macro for timer_fixup()
234  * 
235  * Internal macro for timer_fixup(), performs size fit
236  * check if the timer name matches
237  */
238 #define IF_IS_TIMER_NAME(cell_member, cfg_name) \
239         if ((name->len == sizeof(cfg_name)-1) && \
240                 (memcmp(name->s, cfg_name, sizeof(cfg_name)-1)==0)) { \
241                         SIZE_FIT_CHECK(cell_member, t, cfg_name); \
242         }
243
244 /**
245  * \brief Fixup function for the timer values
246  * 
247  * Fixup function for the timer values, (called by the
248  * configuration framework)
249  * \param handle not used
250  * \param gname not used
251  * \param name not used
252  * \param val fixed timer value
253  * \return 0 on success, -1 on error
254  */
255 int timer_fixup(void *handle, str *gname, str *name, void **val)
256 {
257         ticks_t t;
258
259         t = MS_TO_TICKS((unsigned int)(long)(*val));
260         /* fix 0 values to 1 tick (minimum possible wait time ) */
261         if (t == 0) t = 1;
262
263         /* size fix checks */
264         IF_IS_TIMER_NAME(fr_timeout, "fr_timer")
265         else IF_IS_TIMER_NAME(fr_inv_timeout, "fr_inv_timer")
266         else IF_IS_TIMER_NAME(end_of_life, "max_inv_lifetime")
267         else IF_IS_TIMER_NAME(end_of_life, "max_noninv_lifetime")
268
269         *val = (void *)(long)t;
270         return 0;
271
272 error:
273         return -1;
274 }
275
276
277
278 /** fixup function for timer values that are kept in ms.
279  * (called by the configuration framework)
280  * It checks if the value fits in the tm structures 
281  */
282 int timer_fixup_ms(void *handle, str *gname, str *name, void **val)
283 {
284         long    t;
285
286         t = (long)(*val);
287
288         /* size fix checks */
289 #ifdef TM_DIFF_RT_TIMEOUT
290         IF_IS_TIMER_NAME(rt_t1_timeout_ms, "retr_timer1")
291         else IF_IS_TIMER_NAME(rt_t2_timeout_ms, "retr_timer2")
292 #endif
293
294         return 0;
295
296 error:
297         return -1;
298 }
299
300 /******************** handlers ***************************/
301
302
303 #ifndef TM_DEL_UNREF
304 /* returns number of ticks before retrying the del, or 0 if the del.
305  * was succesfull */
306 inline static ticks_t  delete_cell( struct cell *p_cell, int unlock )
307 {
308         /* there may still be FR/RETR timers, which have been reset
309            (i.e., time_out==TIMER_DELETED) but are stilled linked to
310            timer lists and must be removed from there before the
311            structures are released
312         */
313         unlink_timers( p_cell );
314         /* still in use ... don't delete */
315         if ( IS_REFFED_UNSAFE(p_cell) ) {
316                 if (unlock) UNLOCK_HASH(p_cell->hash_index);
317                 DBG("DEBUG: delete_cell %p: can't delete -- still reffed (%d)\n",
318                                 p_cell, p_cell->ref_count);
319                 /* delay the delete */
320                 /* TODO: change refcnts and delete on refcnt==0 */
321                 return cfg_get(tm, tm_cfg, delete_timeout);
322         } else {
323                 if (unlock) UNLOCK_HASH(p_cell->hash_index);
324 #ifdef EXTRA_DEBUG
325                 DBG("DEBUG: delete transaction %p\n", p_cell );
326 #endif
327                 free_cell( p_cell );
328                 return 0;
329         }
330 }
331 #endif /* TM_DEL_UNREF */
332
333
334
335
336 /* generate a fake reply
337  * it assumes the REPLY_LOCK is already held and returns unlocked */
338 static void fake_reply(struct cell *t, int branch, int code )
339 {
340         struct cancel_info cancel_data;
341         short do_cancel_branch;
342         enum rps reply_status;
343
344         init_cancel_info(&cancel_data);
345         do_cancel_branch = is_invite(t) && prepare_cancel_branch(t, branch, 0);
346         /* mark branch as canceled */
347         t->uac[branch].request.flags|=F_RB_CANCELED;
348         if ( is_local(t) ) {
349                 reply_status=local_reply( t, FAKED_REPLY, branch, 
350                                           code, &cancel_data );
351         } else {
352                 /* rely reply, but don't put on wait, we still need t
353                  * to send the cancels */
354                 reply_status=relay_reply( t, FAKED_REPLY, branch, code,
355                                           &cancel_data, 0 );
356         }
357         /* now when out-of-lock do the cancel I/O */
358 #ifdef CANCEL_REASON_SUPPORT
359         if (do_cancel_branch) cancel_branch(t, branch, &cancel_data.reason, 0);
360 #else /* CANCEL_REASON_SUPPORT */
361         if (do_cancel_branch) cancel_branch(t, branch, 0);
362 #endif /* CANCEL_REASON_SUPPORT */
363         /* it's cleaned up on error; if no error occurred and transaction
364            completed regularly, I have to clean-up myself
365         */
366         if (reply_status == RPS_COMPLETED)
367                 put_on_wait(t);
368 }
369
370
371
372 /* return (ticks_t)-1 on error/disable and 0 on success */
373 inline static ticks_t retransmission_handler( struct retr_buf *r_buf )
374 {
375 #ifdef EXTRA_DEBUG
376         if (r_buf->my_T->flags & T_IN_AGONY) {
377                 LOG( L_ERR, "ERROR: transaction %p scheduled for deletion and"
378                         " called from RETR timer (flags %x)\n",
379                         r_buf->my_T, r_buf->my_T->flags );
380                 abort();
381         }       
382 #endif
383         if ( r_buf->activ_type==TYPE_LOCAL_CANCEL 
384                 || r_buf->activ_type==TYPE_REQUEST ) {
385 #ifdef EXTRA_DEBUG
386                         DBG("DEBUG: retransmission_handler : "
387                                 "request resending (t=%p, %.9s ... )\n", 
388                                 r_buf->my_T, r_buf->buffer);
389 #endif
390                         if (SEND_BUFFER( r_buf )==-1) {
391                                 /* disable retr. timers => return -1 */
392                                 fake_reply(r_buf->my_T, r_buf->branch, 503 );
393                                 return (ticks_t)-1;
394                         }
395 #ifdef TMCB_ONSEND
396                         if (unlikely(has_tran_tmcbs(r_buf->my_T, TMCB_REQUEST_SENT))) 
397                                 run_onsend_callbacks(TMCB_REQUEST_SENT, r_buf, 
398                                                                                 0, 0, TMCB_RETR_F);
399 #endif
400         } else {
401 #ifdef EXTRA_DEBUG
402                         DBG("DEBUG: retransmission_handler : "
403                                 "reply resending (t=%p, %.9s ... )\n", 
404                                 r_buf->my_T, r_buf->buffer);
405 #endif
406                         t_retransmit_reply(r_buf->my_T);
407         }
408         
409         return 0;
410 }
411
412
413
414 inline static void final_response_handler(      struct retr_buf* r_buf,
415                                                                                         struct cell* t)
416 {
417         int silent;
418 #ifdef USE_DNS_FAILOVER
419         /*int i; 
420         int added_branches;
421         */
422         int branch_ret;
423         int prev_branch;
424         ticks_t now;
425 #endif
426
427 #       ifdef EXTRA_DEBUG
428         if (t->flags & T_IN_AGONY) 
429         {
430                 LOG( L_ERR, "ERROR: transaction %p scheduled for deletion and"
431                         " called from FR timer (flags %x)\n", t, t->flags);
432                 abort();
433         }
434 #       endif
435         /* FR for local cancels.... */
436         if (r_buf->activ_type==TYPE_LOCAL_CANCEL)
437         {
438 #ifdef TIMER_DEBUG
439                 DBG("DEBUG: final_response_handler: stop retr for Local Cancel\n");
440 #endif
441                 return;
442         }
443         /* FR for replies (negative INVITE replies) */
444         if (r_buf->activ_type>0) {
445 #               ifdef EXTRA_DEBUG
446                 if (t->uas.request->REQ_METHOD!=METHOD_INVITE
447                         || t->uas.status < 200 ) {
448                         LOG(L_CRIT, "BUG: final_response_handler: unknown type reply"
449                                         " buffer\n");
450                         abort();
451                 }
452 #               endif
453                 put_on_wait( t );
454                 return;
455         };
456
457         /* lock reply processing to determine how to proceed reliably */
458         LOCK_REPLIES( t );
459         /* now it can be only a request retransmission buffer;
460            try if you can simply discard the local transaction 
461            state without compellingly removing it from the
462            world */
463         silent=
464                 /* don't go silent if disallowed globally ... */
465                 cfg_get(tm, tm_cfg, noisy_ctimer)==0
466                 /* ... or for this particular transaction */
467                 && has_noisy_ctimer(t) == 0
468                 /* not for UACs */
469                 && !is_local(t)
470                 /* invites only */
471                 && is_invite(t)
472                 /* parallel forking does not allow silent state discarding */
473                 && t->nr_of_outgoings==1
474                 /* on_negativ reply handler not installed -- serial forking 
475                  * could occur otherwise */
476                 && t->on_negative==0
477                 /* the same for FAILURE callbacks */
478                 && !has_tran_tmcbs( t, TMCB_ON_FAILURE_RO|TMCB_ON_FAILURE) 
479                 /* something received -- we will not be silent on error */
480                 && t->uac[r_buf->branch].last_received==0;
481         
482         if (silent) {
483                 UNLOCK_REPLIES(t);
484 #ifdef EXTRA_DEBUG
485                 DBG("DEBUG: final_response_handler: transaction silently dropped (%p)"
486                                 ", branch %d, last_received %d\n",t, r_buf->branch,
487                                  t->uac[r_buf->branch].last_received);
488 #endif
489                 put_on_wait( t );
490                 return;
491         }
492 #ifdef EXTRA_DEBUG
493         DBG("DEBUG: final_response_handler:stop retr. and send CANCEL (%p)\n", t);
494 #endif
495         if ((r_buf->branch < MAX_BRANCHES) && /* r_buf->branch is always >=0 */
496                         (t->uac[r_buf->branch].last_received==0) &&
497                         (t->uac[r_buf->branch].request.buffer!=NULL) /* not a blind UAC */
498         ){
499                 /* no reply received */
500 #ifdef USE_DST_BLACKLIST
501                 if (r_buf->my_T
502                         && r_buf->my_T->uas.request
503                         && (r_buf->my_T->uas.request->REQ_METHOD &
504                                         cfg_get(tm, tm_cfg, tm_blst_methods_add))
505                 )
506                         dst_blacklist_add( BLST_ERR_TIMEOUT, &r_buf->dst,
507                                                                 r_buf->my_T->uas.request);
508 #endif
509 #ifdef USE_DNS_FAILOVER
510                 /* if this is an invite, the destination resolves to more ips, and
511                  *  it still hasn't passed more than fr_inv_timeout since we
512                  *  started, add another branch/uac */
513                 if (cfg_get(core, core_cfg, use_dns_failover)){
514                         now=get_ticks_raw();
515                         if ((s_ticks_t)(t->end_of_life-now)>0){
516                                 branch_ret=add_uac_dns_fallback(t, t->uas.request,
517                                                                                                         &t->uac[r_buf->branch], 0);
518                                 prev_branch=-1;
519                                 while((branch_ret>=0) &&(branch_ret!=prev_branch)){
520                                         prev_branch=branch_ret;
521                                         branch_ret=t_send_branch(t, branch_ret, t->uas.request , 
522                                                                                                 0, 0);
523                                 }
524                         }
525                 }
526 #endif
527         }
528         fake_reply(t, r_buf->branch, 408);
529 }
530
531
532
533 /* handles retransmissions and fr timers */
534 /* the following assumption are made (to avoid deleting/re-adding the timer):
535  *  retr_buf->retr_interval < ( 1<<((sizeof(ticks_t)*8-1) )
536  *  if retr_buf->retr_interval==0 => timer disabled
537  *                            ==(ticks_t) -1 => retr. disabled (fr working)
538  *     retr_buf->retr_interval & (1 <<(sizeof(ticks_t)*8-1) => retr. & fr reset
539  *     (we never reset only retr, it's either reset both of them or retr 
540  *      disabled & reset fr). In this case the fr_origin will contain the 
541  *      "time" of the reset and next retr should occur at 
542  *      fr->origin+retr_interval (we also assume that we'll never reset retr
543  *      to a lower value then the current one)
544  */
545 ticks_t retr_buf_handler(ticks_t ticks, struct timer_ln* tl, void *p)
546 {
547         struct retr_buf* rbuf ;
548         ticks_t fr_remainder;
549         ticks_t retr_remainder;
550         ticks_t retr_interval;
551         unsigned long new_retr_interval_ms;
552         unsigned long crt_retr_interval_ms;
553         struct cell *t;
554
555         rbuf=(struct  retr_buf*)
556                         ((void*)tl-(void*)(&((struct retr_buf*)0)->timer));
557         membar_depends(); /* to be on the safe side */
558         t=rbuf->my_T;
559         
560 #ifdef TIMER_DEBUG
561         DBG("tm: timer retr_buf_handler @%d (%p -> %p -> %p)\n",
562                         ticks, tl, rbuf, t);
563 #endif
564         if (unlikely(rbuf->flags & F_RB_DEL_TIMER)){
565                 /* timer marked for deletion */
566                 rbuf->t_active=0; /* mark it as removed */
567                 /* a membar is not really needed, in the very unlikely case that 
568                  * another process will see old t_active's value and will try to 
569                  * delete the timer again, but since timer_del it's safe in this cases
570                  * it will be a no-op */
571                 return 0;
572         }
573         /* overflow safe check (should work ok for fr_intervals < max ticks_t/2) */
574         if ((s_ticks_t)(rbuf->fr_expire-ticks)<=0){
575                 /* final response */
576                 rbuf->t_active=0; /* mark the timer as removed 
577                                                          (both timers disabled)
578                                                           a little race risk, but
579                                                           nothing bad would happen */
580                 rbuf->flags|=F_RB_TIMEOUT;
581                 /* WARNING:  the next line depends on taking care not to start the 
582                  *           wait timer before finishing with t (if this is not 
583                  *           guaranteed then comment the timer_allow_del() line) */
584                 timer_allow_del(); /* [optional] allow timer_dels, since we're done
585                                                           and there is no race risk */
586                 final_response_handler(rbuf, t);
587                 return 0;
588         }else{
589                 /*  4 possible states running (t1), t2, paused, disabled */
590                         if ((s_ticks_t)(rbuf->retr_expire-ticks)<=0){
591                                 if (rbuf->flags & F_RB_RETR_DISABLED)
592                                         goto disabled;
593                                 crt_retr_interval_ms = (unsigned long)p;
594                                 /* get the  current interval from timer param. */
595                                 if (unlikely((rbuf->flags & F_RB_T2) ||
596                                                 (crt_retr_interval_ms > RT_T2_TIMEOUT_MS(rbuf)))){
597                                         retr_interval = MS_TO_TICKS(RT_T2_TIMEOUT_MS(rbuf));
598                                         new_retr_interval_ms = RT_T2_TIMEOUT_MS(rbuf);
599                                 }else{
600                                         retr_interval = MS_TO_TICKS(crt_retr_interval_ms);
601                                         new_retr_interval_ms=crt_retr_interval_ms<<1;
602                                 }
603 #ifdef TIMER_DEBUG
604                                 DBG("tm: timer: retr: new interval %ld ms / %d ticks"
605                                                 " (max %d ms)\n", new_retr_interval_ms, retr_interval,
606                                                 RT_T2_TIMEOUT_MS(rbuf));
607 #endif
608                                 /* we could race with the reply_received code, but the 
609                                  * worst thing that can happen is to delay a reset_to_t2
610                                  * for crt_interval and send an extra retr.*/
611                                 rbuf->retr_expire=ticks+retr_interval;
612                                 /* set new interval to -1 on error, or retr_int. on success */
613                                 retr_remainder=retransmission_handler(rbuf) | retr_interval;
614                                 /* store the next retr. interval in ms inside the timer struct,
615                                  * in the data member */
616                                 tl->data=(void*)(new_retr_interval_ms);
617                         }else{
618                                 retr_remainder= rbuf->retr_expire-ticks;
619                                 DBG("tm: timer: retr: nothing to do, expire in %d\n", 
620                                                 retr_remainder);
621                         }
622         }
623 /* skip: */
624         /* return minimum of the next retransmission handler and the 
625          * final response (side benefit: it properly cancels timer if ret==0 and
626          *  sleeps for fr_remainder if retr. is canceled [==(ticks_t)-1]) */
627         fr_remainder=rbuf->fr_expire-ticks; /* to be more precise use
628                                                                                         get_ticks_raw() instead of ticks
629                                                                                         (but make sure that 
630                                                                                         crt. ticks < fr_expire */
631 #ifdef TIMER_DEBUG
632         DBG("tm: timer retr_buf_handler @%d (%p ->%p->%p) exiting min (%d, %d)\n",
633                         ticks, tl, rbuf, t, retr_remainder, fr_remainder);
634 #endif
635 #ifdef EXTRA_DEBUG
636         if  (retr_remainder==0 || fr_remainder==0){
637                 BUG("tm: timer retr_buf_handler: 0 remainder => disabling timer!: "
638                                 "retr_remainder=%d, fr_remainder=%d\n", retr_remainder,
639                                 fr_remainder);
640         }
641 #endif
642         if (retr_remainder<fr_remainder)
643                 return retr_remainder;
644         else{
645                 /* hack to switch to the slow timer */
646 #ifdef TM_FAST_RETR_TIMER
647                 tl->flags&=~F_TIMER_FAST;
648 #endif
649                 return fr_remainder;
650         }
651 disabled:
652         return rbuf->fr_expire-ticks;
653 }
654
655
656
657 ticks_t wait_handler(ticks_t ti, struct timer_ln *wait_tl, void* data)
658 {
659         struct cell *p_cell;
660         ticks_t ret;
661
662         p_cell=(struct cell*)data;
663 #ifdef TIMER_DEBUG
664         DBG("DEBUG: WAIT timer hit @%d for %p (timer_lm %p)\n", 
665                         ti, p_cell, wait_tl);
666 #endif
667
668 #ifdef TM_DEL_UNREF
669         /* stop cancel timers if any running */
670         if ( is_invite(p_cell) ) cleanup_localcancel_timers( p_cell );
671         /* remove the cell from the hash table */
672         LOCK_HASH( p_cell->hash_index );
673         remove_from_hash_table_unsafe(  p_cell );
674         UNLOCK_HASH( p_cell->hash_index );
675         p_cell->flags |= T_IN_AGONY;
676         UNREF_FREE(p_cell);
677         ret=0;
678 #else /* TM_DEL_UNREF */
679         if (p_cell->flags & T_IN_AGONY){
680                 /* delayed delete */
681                 /* we call delete now without any locking on hash/ref_count;
682                    we can do that because delete_handler is only entered after
683                    the delete timer was installed from wait_handler, which
684                    removed transaction from hash table and did not destroy it
685                    because some processes were using it; that means that the
686                    processes currently using the transaction can unref and no
687                    new processes can ref -- we can wait until ref_count is
688                    zero safely without locking
689                 */
690                 ret=delete_cell( p_cell, 0 /* don't unlock on return */ );
691         }else {
692                 /* stop cancel timers if any running */
693                 if ( is_invite(p_cell) ) cleanup_localcancel_timers( p_cell );
694                 /* remove the cell from the hash table */
695                 LOCK_HASH( p_cell->hash_index );
696                 remove_from_hash_table_unsafe(  p_cell );
697                 p_cell->flags |= T_IN_AGONY;
698                 /* delete (returns with UNLOCK-ed_HASH) */
699                 ret=delete_cell( p_cell, 1 /* unlock on return */ );
700         }
701 #endif /* TM_DEL_UNREF */
702         return ret;
703 }
704