[sr-dev] git:master: tm: experimental tm onreply_route final reply DROP support

Andrei Pelinescu-Onciul andrei at iptel.org
Fri Feb 26 15:13:36 CET 2010


Module: sip-router
Branch: master
Commit: e81c62ec2fd8666fc5b3a86c33e55e40029f2349
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e81c62ec2fd8666fc5b3a86c33e55e40029f2349

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at 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) {




More information about the sr-dev mailing list