<p>N A has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18577">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">app_confbridge: Fix bridge shutdown race condition.<br><br>A race condition exists where if a bridge is left vacant<br>for a split instant, the bridge will shut down and go<br>away at the same instant that somebody else could be trying<br>to join it. The newcomer will find the conference still<br>in conference_bridges and thus take it and run with it.<br>At the same time, shutdown of the bridge completes and it<br>is removed from conference_bridges. This would generally<br>be rare since the timing must line up exactly right, but<br>if the timing is right, it can happen very frequently.<br><br>As a result, the newcomer will end up joining the bridge<br>corresponding to the original conference that is now<br>defunct. When the next party joins the same named bridge,<br>it won't be found in conference_bridges and thus a new<br>bridge gets created. This can happen right afterwards,<br>but in theory it could happen at any point after the first.<br><br>As a result, the newcomer that joined the bridge during<br>the shutdown ends up stranded in a bridge that isn't<br>known to app_confbridge anymore and will never get conferenced<br>with anything, since it's been removed from the list of<br>conferences already.<br><br>To prevent this, we now check after we join the bridge<br>if the same conference object is returned when searching<br>for it. If it isn't, then we try to join the bridge again,<br>which will succeed the second time since we won't find<br>the shutting down conference anymore.<br><br>ASTERISK-30081 #close<br><br>Change-Id: I08a440eafbf83ec4b502d1e44c3f4d44c4a522f9<br>---<br>M apps/app_confbridge.c<br>1 file changed, 19 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/77/18577/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c</span><br><span>index ae17bca..6c46020 100644</span><br><span>--- a/apps/app_confbridge.c</span><br><span>+++ b/apps/app_confbridge.c</span><br><span>@@ -1728,10 +1728,11 @@</span><br><span>  */</span><br><span> static struct confbridge_conference *join_conference_bridge(const char *conference_name, struct confbridge_user *user)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     struct confbridge_conference *conference;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct confbridge_conference *conference, *conference2;</span><br><span>      struct post_join_action *action;</span><br><span>     int max_members_reached = 0;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+attempt:</span><br><span>   /* We explicitly lock the conference bridges container ourselves so that other callers can not create duplicate conferences at the same */</span><br><span>   ao2_lock(conference_bridges);</span><br><span> </span><br><span>@@ -1902,6 +1903,21 @@</span><br><span>           return NULL;</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Rare, but if threads interleave exactly right, the bridge could disappear</span><br><span style="color: hsl(120, 100%, 40%);">+   * just AFTER we found it. At this point, it's not empty anymore, so if it's</span><br><span style="color: hsl(120, 100%, 40%);">+   * still intact, it's safe to use. If not, then start over, or we'll end</span><br><span style="color: hsl(120, 100%, 40%);">+       * up joining a ghost bridge that isn't registered anymore in the conf list. */</span><br><span style="color: hsl(120, 100%, 40%);">+   conference2 = ao2_find(conference_bridges, conference_name, OBJ_KEY);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (conference != conference2) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ao2_unlock(conference);</span><br><span style="color: hsl(120, 100%, 40%);">+               leave_conference(user);</span><br><span style="color: hsl(120, 100%, 40%);">+               ast_debug(1, "Conference (bridge %p) %s before we could join it\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                 conference->bridge, conference2 ? "changed" : "disappeared");</span><br><span style="color: hsl(120, 100%, 40%);">+          goto attempt;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ao2_ref(conference2, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  ao2_unlock(conference);</span><br><span> </span><br><span>  /* If an announcement is to be played play it */</span><br><span>@@ -2845,6 +2861,8 @@</span><br><span>             async_play_sound_ready(user.chan);</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(2, "Joining conference in bridge %p\n", conference->bridge);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        ast_bridge_join(conference->bridge,</span><br><span>               chan,</span><br><span>                NULL,</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18577">change 18577</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/18577"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I08a440eafbf83ec4b502d1e44c3f4d44c4a522f9 </div>
<div style="display:none"> Gerrit-Change-Number: 18577 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: N A <mail@interlinked.x10host.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>