瀏覽代碼

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 11 年之前
父節點
當前提交
7f50e172c2
共有 4 個文件被更改,包括 54 次插入2 次删除
  1. 26 2
      modules/tm/doc/functions.xml
  2. 1 0
      modules/tm/h_table.h
  3. 1 0
      modules/tm/t_suspend.c
  4. 26 0
      modules/tm/tm.c

+ 26 - 2
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>

+ 1 - 0
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 */

+ 1 - 0
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){

+ 26 - 0
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)
 {