Module: sip-router Branch: master Commit: e81c62ec2fd8666fc5b3a86c33e55e40029f2349 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e81c62ec...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Fri Feb 26 15:10:49 2010 +0100
tm: experimental tm onreply_route final reply DROP support
Experimental support for dropping final replies from tm onreply_route[]s. It's disabled by default (causes a small performance hit and it's not needed in most cases). To enable re-compile tm with -DTM_ONREPLY_FINAL_DROP_OK (e.g. make cfg extra_defs=-DTM_ONREPLY_FINAL_DROP_OK; make all or make -C modules/tm extra_defs=-DTM_ONREPLY_FINAL_DROP_OK)
---
modules/tm/t_reply.c | 65 +++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/modules/tm/t_reply.c b/modules/tm/t_reply.c index 9fbe6c3..f28cf05 100644 --- a/modules/tm/t_reply.c +++ b/modules/tm/t_reply.c @@ -94,9 +94,17 @@ * 2009-12-10 reply route is executed under lock to protect the avps (andrei) * 2010-02-22 _reply() will cleanup any reply lumps that it might have added * (andrei) + * 2010-02-26 added experimental support for final reply dropping, not + * enabled by default (performance hit) (andrei) * */
+ /* Defines: + * TM_ONREPLY_FINAL_DROP_OK - allows dropping the final reply + * from the tm onreply_routes, but comes with a small performance + * hit (extra unlock()/lock() for each final reply when a onreply + * route is set). + */
#ifdef EXTRA_DEBUG #include <assert.h> @@ -147,6 +155,10 @@ #include "uac.h"
+#ifdef NO_TM_ONREPLY_FINAL_DROP_OK +#undef TM_ONREPLY_FINAL_DROP_OK +#endif + /* private place where we create to-tags for replies */ /* janakj: made public, I need to access this value to store it in dialogs */ char tm_tags[TOTAG_VALUE_LEN]; @@ -1880,6 +1892,7 @@ int reply_received( struct sip_msg *p_msg ) int branch; /* has the transaction completed now and we need to clean-up? */ int reply_status; + int onreply_route; branch_bm_t cancel_bitmap; struct ua_client *uac; struct cell *t; @@ -1939,11 +1952,20 @@ int reply_received( struct sip_msg *p_msg ) DBG("DEBUG: reply to local CANCEL processed\n"); goto done; } - - + + onreply_route=t->on_reply; if ( msg_status >= 200 ){ - /* stop final response timer & retr. only if I got a final response */ - stop_rb_timers(&uac->request); +#ifdef TM_ONREPLY_FINAL_DROP_OK +#warning Experimental tm onreply_route final reply DROP support active + if (onreply_route) + /* stop only retr., but leave the final reply timers on, in case + the final reply is dropped in the on_reply route */ + stop_rb_retr(&uac->request); + else +#endif /* TM_ONREPLY_FINAL_DROP_OK */ + /* stop final response timer & retr. if I got a + final response */ + stop_rb_timers(&uac->request); /* acknowledge negative INVITE replies (do it before detailed * on_reply processing, which may take very long, like if it * is attempted to establish a TCP connection to a fail-over dst */ @@ -2030,7 +2052,7 @@ int reply_received( struct sip_msg *p_msg ) p_msg->fwd_send_flags.blst_imask|= uac->request.dst.send_flags.blst_imask & BLST_503; /* processing of on_reply block */ - if (t->on_reply) { + if (onreply_route) { set_route_type(TM_ONREPLY_ROUTE); /* transfer transaction flag to message context */ if (t->uas.request) p_msg->flags=t->uas.request->flags; @@ -2052,7 +2074,7 @@ int reply_received( struct sip_msg *p_msg ) /* lock onreply_route, for safe avp usage */ LOCK_REPLIES( t ); replies_locked=1; - run_top_route(onreply_rt.rlist[t->on_reply], p_msg, &ctx); + run_top_route(onreply_rt.rlist[onreply_route], p_msg, &ctx); /* transfer current message context back to t */ if (t->uas.request) t->uas.request->flags=p_msg->flags; getbflagsval(0, &uac->branch_flags); @@ -2070,13 +2092,36 @@ int reply_received( struct sip_msg *p_msg ) /* handle a possible DROP in the script, but only if this is not a final reply (final replies already stop the timers and droping them might leave a transaction living forever) */ - if ((ctx.run_flags&DROP_R_F) && (msg_status<200)) { - if (unlikely(replies_locked)) { +#ifdef TM_ONREPLY_FINAL_DROP_OK + if (unlikely(ctx.run_flags&DROP_R_F)) +#else + if (unlikely((ctx.run_flags&DROP_R_F) && (msg_status<200))) +#endif /* TM_ONREPLY_FINAL_DROP_OK */ + { + if (likely(replies_locked)) { replies_locked = 0; UNLOCK_REPLIES( t ); } goto done; } +#ifdef TM_ONREPLY_FINAL_DROP_OK + if (msg_status >= 200) { + /* stop final reply timers, now that we executed the onreply route + and the reply was not DROPed */ + if (likely(replies_locked)){ + /* if final reply => we have to execute stop_rb_timers, but + with replies unlocked to avoid a possible deadlock + (if the timer is currently running, stop_rb_timers() + will wait until the timer handler ends, but the + final_response_handler() will try to lock replies => + deadlock). + */ + UNLOCK_REPLIES( t ); + replies_locked=0; + } + stop_rb_timers(&uac->request); + } +#endif /* TM_ONREPLY_FINAL_DROP_OK */ } #ifdef USE_DST_BLACKLIST /* add temporary to the blacklist the source of a 503 reply */ @@ -2129,8 +2174,10 @@ int reply_received( struct sip_msg *p_msg ) } } #endif - if (unlikely(!replies_locked)) + if (unlikely(!replies_locked)){ LOCK_REPLIES( t ); + replies_locked=1; + } if ( is_local(t) ) { reply_status=local_reply( t, p_msg, branch, msg_status, &cancel_bitmap ); if (reply_status == RPS_COMPLETED) {