Module: sip-router
Branch: master
Commit: d4cef7f5e49105c65df9651a1ad086b035f8ffdb
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d4cef7f…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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 */