Module: sip-router
Branch: master
Commit: e81c62ec2fd8666fc5b3a86c33e55e40029f2349
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e81c62e…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)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) {