]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_sip: Fix missed locking of opposing pvt for directmedia acl from r366547
authorJonathan Rose <jrose@digium.com>
Thu, 17 May 2012 14:41:13 +0000 (14:41 +0000)
committerJonathan Rose <jrose@digium.com>
Thu, 17 May 2012 14:41:13 +0000 (14:41 +0000)
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

channels/chan_sip.c

index c1272dfa40c9f676a03665e9338cebbbc6c27fe3..494f45df8a5509c021a9b2ae97aa05049eaf021f 100644 (file)
@@ -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;