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