[sr-dev] git:master: modules/tm: new function t_is_retr_async_reply to check if a reply being processed is part of a transaction currently suspended

Jason Penton jason.penton at gmail.com
Fri Oct 10 10:46:17 CEST 2014


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

Author: Jason Penton <jason.penton at gmail.com>
Committer: Jason Penton <jason.penton at gmail.com>
Date:   Fri Oct 10 10:44:49 2014 +0200

modules/tm: new function t_is_retr_async_reply to check if a reply being processed is part of a transaction currently suspended

---

 modules/tm/doc/functions.xml |   28 ++++++++++++++++++++++++++--
 modules/tm/h_table.h         |    1 +
 modules/tm/t_suspend.c       |    1 +
 modules/tm/tm.c              |   26 ++++++++++++++++++++++++++
 4 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/modules/tm/doc/functions.xml b/modules/tm/doc/functions.xml
index af7d11d..9d42cf3 100644
--- a/modules/tm/doc/functions.xml
+++ b/modules/tm/doc/functions.xml
@@ -1723,5 +1723,29 @@ t_use_uac_headers();
 	    </programlisting>
 	</example>
     </section>
-
-</section>
+	<section id="tm.f.t_is_retr_async_reply">
+	<title>                                                               </section>
+	    <function>t_is_retr_async_reply()</function>
+	</title>
+	<para>
+	Check to see if the reply is a retransmitted reply on a transaction that is 
+	currently suspended asynchronously (suspended during reply processing). Right now the check is only on the 
+	transaction, we don't actually check to see if the reply message is an actual 
+	retransmission of the suspended reply. This is expected as you should not process 
+	another reply until the suspended reply processing has been completed. The trick here 
+	is to make sure you don't suspend for too long or even worse, indefinitely.
+	</para>
+	<para>returns true if the transaction is currently reply suspended or false if not.</para>
+	<example>
+	    <title><function>t_is_retr_async_reply</function> usage</title>
+	    <programlisting>
+...
+if (t_is_retr_async_reply()) {
+	xlog("L_DBG", "Dropping retransmitted reply which is still currently suspended\n");
+        drop();
+}
+...
+	    </programlisting>
+	</example>
+    </section>
+    </section>
diff --git a/modules/tm/h_table.h b/modules/tm/h_table.h
index 50a711d..42551bb 100644
--- a/modules/tm/h_table.h
+++ b/modules/tm/h_table.h
@@ -322,6 +322,7 @@ typedef struct async_state {
 
 #define T_DISABLE_INTERNAL_REPLY (1<<13) /* don't send internal negative reply */
 #define T_ADMIN_REPLY (1<<14) /* t reply sent by admin (e.g., from cfg script) */
+#define T_ASYNC_SUSPENDED (1<<15)
 
 /* 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 */
diff --git a/modules/tm/t_suspend.c b/modules/tm/t_suspend.c
index 435686a..1d7e3ca 100644
--- a/modules/tm/t_suspend.c
+++ b/modules/tm/t_suspend.c
@@ -108,6 +108,7 @@ int t_suspend(struct sip_msg *msg,
 	} else {
 		LM_DBG("this is a suspend on reply - setting msg flag to SUSPEND\n");
 		msg->msg_flags |= FL_RPL_SUSPENDED;
+                t->flags |= T_ASYNC_SUSPENDED;
 		/* this is a reply suspend find which branch */
 
 		if (t_check( msg  , &branch )==-1){
diff --git a/modules/tm/tm.c b/modules/tm/tm.c
index 5b92055..54bcc78 100644
--- a/modules/tm/tm.c
+++ b/modules/tm/tm.c
@@ -298,6 +298,7 @@ static int t_any_timeout(struct sip_msg* msg, char*, char*);
 static int t_any_replied(struct sip_msg* msg, char*, char*);
 static int w_t_is_canceled(struct sip_msg* msg, char*, char*);
 static int t_is_expired(struct sip_msg* msg, char*, char*);
+static int w_t_is_retr_async_reply(struct sip_msg* msg, char*, char*);
 static int t_grep_status(struct sip_msg* msg, char*, char*);
 static int w_t_drop_replies(struct sip_msg* msg, char* foo, char* bar);
 static int w_t_save_lumps(struct sip_msg* msg, char* foo, char* bar);
@@ -472,6 +473,8 @@ static cmd_export_t cmds[]={
 			REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
 	{"t_is_canceled",     w_t_is_canceled,          0, 0,
 			REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
+        {"t_is_retr_async_reply",     w_t_is_retr_async_reply,          0, 0,
+			TM_ONREPLY_ROUTE},                
 	{"t_is_expired",      t_is_expired,             0, 0,
 			REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
 	{"t_grep_status",     t_grep_status,            1, fixup_var_int_1, 
@@ -1950,6 +1953,29 @@ static int w_t_is_canceled(struct sip_msg* msg, char* foo, char* bar)
 	return t_is_canceled(msg);
 }
 
+/* script function, returns: 1 if the transaction is currently suspended, -1 if not */
+int t_is_retr_async_reply(struct sip_msg* msg)
+{
+	struct cell *t;
+	int ret;	
+	
+	if (t_check( msg , 0 )==-1) return -1;
+	t=get_t();
+	if ((t==0) || (t==T_UNDEFINED)){
+		LOG(L_ERR, "ERROR: t_is_retr_async_reply: cannot check a message "
+			"for which no T-state has been established\n");
+		ret=-1;
+	}else{
+        LOG(L_DBG, "TRANSACTION FLAGS IS %d\n", t->flags);
+		ret=(t->flags & T_ASYNC_SUSPENDED)?1:-1;
+	}
+	return ret;
+}
+static int w_t_is_retr_async_reply(struct sip_msg* msg, char* foo, char* bar)
+{
+	return t_is_retr_async_reply(msg);
+}
+
 /* script function, returns: 1 if the transaction lifetime interval has already elapsed, -1 if not */
 int t_is_expired(struct sip_msg* msg, char* foo, char* bar)
 {




More information about the sr-dev mailing list