|
@@ -89,7 +89,9 @@
|
|
|
* 2008-03-12 use cancel_b_method on 6xx (andrei)
|
|
|
* 2008-05-30 make sure the wait timer is started after we don't need t
|
|
|
* anymore to allow safe calls from fr_timer (andrei)
|
|
|
- * 2009-06-01 Pre- and post-script callbacks of branch route are executed (Miklos)
|
|
|
+ * 2009-06-01 Pre- and post-script callbacks of branch route are
|
|
|
+ * executed (Miklos)
|
|
|
+ * 2009-12-10 reply route is executed under lock to protect the avps (andrei)
|
|
|
*
|
|
|
*/
|
|
|
|
|
@@ -1861,6 +1863,7 @@ int reply_received( struct sip_msg *p_msg )
|
|
|
#ifdef WITH_XAVP
|
|
|
sr_xavp_t **backup_xavps;
|
|
|
#endif
|
|
|
+ int replies_locked;
|
|
|
#ifdef USE_DNS_FAILOVER
|
|
|
int branch_ret;
|
|
|
int prev_branch;
|
|
@@ -1888,6 +1891,7 @@ int reply_received( struct sip_msg *p_msg )
|
|
|
tm_ctx_set_branch_index(branch);
|
|
|
cancel_bitmap=0;
|
|
|
msg_status=p_msg->REPLY_STATUS;
|
|
|
+ replies_locked=0;
|
|
|
|
|
|
uac=&t->uac[branch];
|
|
|
DBG("DEBUG: reply_received: org. status uas=%d, "
|
|
@@ -2015,6 +2019,9 @@ int reply_received( struct sip_msg *p_msg )
|
|
|
/* Pre- and post-script callbacks have already
|
|
|
* been executed by the core. (Miklos)
|
|
|
*/
|
|
|
+ /* lock onreply_route, for safe avp usage */
|
|
|
+ LOCK_REPLIES( t );
|
|
|
+ replies_locked=1;
|
|
|
run_top_route(onreply_rt.rlist[t->on_reply], p_msg, &ctx);
|
|
|
if ((ctx.run_flags&DROP_R_F) && (msg_status<200)) {
|
|
|
goto done;
|
|
@@ -2071,15 +2078,22 @@ int reply_received( struct sip_msg *p_msg )
|
|
|
* reply lock is held (the lock won't be held while sending the
|
|
|
* message)*/
|
|
|
if (cfg_get(core, core_cfg, use_dns_failover) && (msg_status==503)) {
|
|
|
- branch_ret=add_uac_dns_fallback(t, t->uas.request, uac, 1);
|
|
|
+ branch_ret=add_uac_dns_fallback(t, t->uas.request,
|
|
|
+ uac, !replies_locked);
|
|
|
prev_branch=-1;
|
|
|
+ /* unlock replies to avoid sending() while holding a lock */
|
|
|
+ if (unlikely(replies_locked)) {
|
|
|
+ UNLOCK_REPLIES( t );
|
|
|
+ replies_locked = 0;
|
|
|
+ }
|
|
|
while((branch_ret>=0) &&(branch_ret!=prev_branch)){
|
|
|
prev_branch=branch_ret;
|
|
|
branch_ret=t_send_branch(t, branch_ret, t->uas.request , 0, 1);
|
|
|
}
|
|
|
}
|
|
|
#endif
|
|
|
- LOCK_REPLIES( t );
|
|
|
+ if (unlikely(!replies_locked))
|
|
|
+ LOCK_REPLIES( t );
|
|
|
if ( is_local(t) ) {
|
|
|
reply_status=local_reply( t, p_msg, branch, msg_status, &cancel_bitmap );
|
|
|
if (reply_status == RPS_COMPLETED) {
|