From: Jonathan Rose Date: Thu, 17 May 2012 14:41:13 +0000 (+0000) Subject: chan_sip: Fix missed locking of opposing pvt for directmedia acl from r366547 X-Git-Tag: 10.6.0-rc1~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b2f92847d142d753355d2a2491e9d20ce38dd54;p=thirdparty%2Fasterisk.git chan_sip: Fix missed locking of opposing pvt for directmedia acl from r366547 It also required deadlock avoidance since two sip_pvts structs needed to be locked simultaneously. Trunk handles it differently, so this is a 1.8 and 10 patch only. ........ (issue AST-876) Merged revisions 366791 from http://svn.asterisk.org/svn/asterisk/branches/1.8 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10@366792 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/channels/chan_sip.c b/channels/chan_sip.c index c1272dfa40..494f45df8a 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -30003,11 +30003,19 @@ static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan) } sip_pvt_lock(p); + while (sip_pvt_trylock(opp)) { + sip_pvt_unlock(p); + usleep(1); + sip_pvt_lock(p); + } + if (p->udptl && ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { if (apply_directmedia_ha(p, opp, "UDPTL T.38 data")) { udptl = p->udptl; } } + + sip_pvt_unlock(opp); sip_pvt_unlock(p); return udptl; } @@ -30073,7 +30081,14 @@ static enum ast_rtp_glue_result sip_get_rtp_peer(struct ast_channel *chan, struc } sip_pvt_lock(p); + while (sip_pvt_trylock(opp)) { + sip_pvt_unlock(p); + usleep(1); + sip_pvt_lock(p); + } + if (!(p->rtp)) { + sip_pvt_unlock(opp); sip_pvt_unlock(p); return AST_RTP_GLUE_RESULT_FORBID; } @@ -30092,6 +30107,8 @@ static enum ast_rtp_glue_result sip_get_rtp_peer(struct ast_channel *chan, struc res = AST_RTP_GLUE_RESULT_FORBID; } + sip_pvt_unlock(opp); + if (p->srtp) { res = AST_RTP_GLUE_RESULT_FORBID; } @@ -30119,7 +30136,14 @@ static enum ast_rtp_glue_result sip_get_vrtp_peer(struct ast_channel *chan, stru } sip_pvt_lock(p); + while (sip_pvt_trylock(opp)) { + sip_pvt_unlock(p); + usleep(1); + sip_pvt_lock(p); + } + if (!(p->vrtp)) { + sip_pvt_unlock(opp); sip_pvt_unlock(p); return AST_RTP_GLUE_RESULT_FORBID; } @@ -30134,6 +30158,7 @@ static enum ast_rtp_glue_result sip_get_vrtp_peer(struct ast_channel *chan, stru } } + sip_pvt_unlock(opp); sip_pvt_unlock(p); return res; @@ -30157,7 +30182,14 @@ static enum ast_rtp_glue_result sip_get_trtp_peer(struct ast_channel *chan, stru } sip_pvt_lock(p); + while (sip_pvt_trylock(opp)) { + sip_pvt_unlock(p); + usleep(1); + sip_pvt_lock(p); + } + if (!(p->trtp)) { + sip_pvt_unlock(opp); sip_pvt_unlock(p); return AST_RTP_GLUE_RESULT_FORBID; } @@ -30172,6 +30204,7 @@ static enum ast_rtp_glue_result sip_get_trtp_peer(struct ast_channel *chan, stru } } + sip_pvt_unlock(opp); sip_pvt_unlock(p); return res;