[sr-dev] git:master: tm: avoid double execution of response-in callbacks

Daniel-Constantin Mierla miconda at gmail.com
Thu Jul 4 11:51:00 CEST 2013


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

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Thu Jul  4 11:48:26 2013 +0200

tm: avoid double execution of response-in callbacks

- double execution of response-in callbacks could happen when using tm
  pvs inside core reply route, being done in transaction matching
  function, which is executed again by tm reply received function

---

 modules/tm/t_lookup.c |   55 ++++++++++++++++++++++++++----------------------
 1 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/modules/tm/t_lookup.c b/modules/tm/t_lookup.c
index 8c34a81..fbc624b 100644
--- a/modules/tm/t_lookup.c
+++ b/modules/tm/t_lookup.c
@@ -1001,33 +1001,38 @@ int t_reply_matching( struct sip_msg *p_msg , int *p_branch )
 		REF_UNSAFE( T );
 		UNLOCK_HASH(hash_index);
 		DBG("DEBUG: t_reply_matching: reply matched (T=%p)!\n",T);
-		/* if this is a 200 for INVITE, we will wish to store to-tags to be
-		 * able to distinguish retransmissions later and not to call
- 		 * TMCB_RESPONSE_OUT uselessly; we do it only if callbacks are
-		 * enabled -- except callback customers, nobody cares about 
-		 * retransmissions of multiple 200/INV or ACK/200s
-		 */
-		if (unlikely( is_invite(p_cell) && p_msg->REPLY_STATUS>=200 
-			&& p_msg->REPLY_STATUS<300 
-			&& ((!is_local(p_cell) &&
-				has_tran_tmcbs(p_cell, 
-					TMCB_RESPONSE_OUT|TMCB_RESPONSE_READY
-					|TMCB_E2EACK_IN|TMCB_E2EACK_RETR_IN) )
-			|| (is_local(p_cell)&&has_tran_tmcbs(p_cell, TMCB_LOCAL_COMPLETED))
-		)) ) {
-			if (parse_headers(p_msg, HDR_TO_F, 0)==-1) {
-				LOG(L_ERR, "ERROR: t_reply_matching: to parsing failed\n");
+		if(likely(!(p_msg->msg_flags&FL_TM_RPL_MATCHED))) {
+			/* if this is a 200 for INVITE, we will wish to store to-tags to be
+			 * able to distinguish retransmissions later and not to call
+			 * TMCB_RESPONSE_OUT uselessly; we do it only if callbacks are
+			 * enabled -- except callback customers, nobody cares about
+			 * retransmissions of multiple 200/INV or ACK/200s
+			 */
+			if (unlikely( is_invite(p_cell) && p_msg->REPLY_STATUS>=200
+				&& p_msg->REPLY_STATUS<300
+				&& ((!is_local(p_cell) &&
+					has_tran_tmcbs(p_cell,
+						TMCB_RESPONSE_OUT|TMCB_RESPONSE_READY
+						|TMCB_E2EACK_IN|TMCB_E2EACK_RETR_IN) )
+				|| (is_local(p_cell)&&has_tran_tmcbs(p_cell, TMCB_LOCAL_COMPLETED))
+			)) ) {
+				if (parse_headers(p_msg, HDR_TO_F, 0)==-1) {
+					LOG(L_ERR, "ERROR: t_reply_matching: to parsing failed\n");
+				}
 			}
-		}
-		if (unlikely(has_tran_tmcbs(T, TMCB_RESPONSE_IN |
-										TMCB_LOCAL_RESPONSE_IN))){
-			if (!is_local(p_cell)) {
-				run_trans_callbacks( TMCB_RESPONSE_IN, T, T->uas.request,
-										p_msg, p_msg->REPLY_STATUS);
-			}else{
-				run_trans_callbacks( TMCB_LOCAL_RESPONSE_IN, T, T->uas.request,
-										p_msg, p_msg->REPLY_STATUS);
+			if (unlikely(has_tran_tmcbs(T, TMCB_RESPONSE_IN |
+											TMCB_LOCAL_RESPONSE_IN))){
+				if (!is_local(p_cell)) {
+					run_trans_callbacks( TMCB_RESPONSE_IN, T, T->uas.request,
+											p_msg, p_msg->REPLY_STATUS);
+				}else{
+					run_trans_callbacks( TMCB_LOCAL_RESPONSE_IN, T, T->uas.request,
+											p_msg, p_msg->REPLY_STATUS);
+				}
 			}
+			p_msg->msg_flags |= FL_TM_RPL_MATCHED;
+		} else {
+			DBG("reply in callbacks already done (T=%p)!\n", T);
 		}
 		return 1;
 	} /* for cycle */




More information about the sr-dev mailing list