Module: sip-router Branch: sr_3.0 Commit: b577291770fbae2d9df294529dd852acd760c4d6 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=b5772917...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Thu Dec 10 18:35:17 2009 +0100
tm: onreply_route executed under lock to protect the avps
Quick fix for the onreply_route possible avp corruption: execute the onreply route under lock.
---
modules/tm/t_reply.c | 20 +++++++++++++++++--- 1 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/modules/tm/t_reply.c b/modules/tm/t_reply.c index 28e635e..8dbd1d6 100644 --- a/modules/tm/t_reply.c +++ b/modules/tm/t_reply.c @@ -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) * */
@@ -1834,6 +1836,7 @@ int reply_received( struct sip_msg *p_msg ) avp_list_t* backup_user_from, *backup_user_to; avp_list_t* backup_domain_from, *backup_domain_to; avp_list_t* backup_uri_from, *backup_uri_to; + int replies_locked; #ifdef USE_DNS_FAILOVER int branch_ret; int prev_branch; @@ -1860,6 +1863,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, " @@ -1984,6 +1988,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; if (run_top_route(onreply_rt.rlist[t->on_reply], p_msg, 0)<0) LOG(L_ERR, "ERROR: on_reply processing failed\n"); /* transfer current message context back to t */ @@ -2035,15 +2042,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) {