<p>Richard Mudgett has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/8731">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">chan_sip.c: Fix INVITE with replaces channel ref leak.<br><br>Given the below call scenario:<br>A -> Ast1 -> B<br>C <- Ast2 <- B<br><br>1) A calls B through Ast1<br>2) B calls C through Ast2<br>3) B transfers A to C<br><br>When party B transfers A to C, B sends a REFER to Ast1 causing Ast1 to<br>send an INVITE with replaces to Ast2. Ast2 then leaks a channel ref of<br>the channel between Ast1 and Ast2.<br><br>Channel ref leaks are easily seen in the CLI "core show channels" output.<br>The leaked channels appear in the output but you can do nothing with them<br>and they never go away unless you restart Asterisk.<br><br>* Properly account for the channel refs when imparting a channel into a<br>bridge when handling an INVITE with replaces in handle_invite_replaces().<br>The ast_bridge_impart() function steals a channel ref but the code didn't<br>account for how many refs were held by the code at the time and which ref<br>was stolen.<br><br>* Eliminated RAII_VAR in handle_invite_replaces().<br><br>ASTERISK-27740<br><br>Change-Id: I7edbed774314b55acf0067b2762bfe984ecaa9a4<br>---<br>M channels/chan_sip.c<br>1 file changed, 10 insertions(+), 4 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/31/8731/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/channels/chan_sip.c b/channels/chan_sip.c<br>index cc4dd26..a259dea 100644<br>--- a/channels/chan_sip.c<br>+++ b/channels/chan_sip.c<br>@@ -25695,7 +25695,7 @@<br> int *nounlock, struct sip_pvt *replaces_pvt, struct ast_channel *replaces_chan)<br> {<br> struct ast_channel *c;<br>- RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);<br>+ struct ast_bridge *bridge;<br> <br> if (req->ignore) {<br> return 0;<br>@@ -25711,6 +25711,7 @@<br> }<br> append_history(p, "Xfer", "INVITE/Replace received");<br> <br>+ /* Get a ref to ensure the channel cannot go away on us. */<br> c = ast_channel_ref(p->owner);<br> <br> /* Fake call progress */<br>@@ -25728,18 +25729,23 @@<br> ast_channel_lock(replaces_chan);<br> bridge = ast_channel_get_bridge(replaces_chan);<br> ast_channel_unlock(replaces_chan);<br>-<br> if (bridge) {<br>+ /*<br>+ * We have two refs of the channel. One is held in c and the other<br>+ * is notionally represented by p->owner. The impart is "stealing"<br>+ * the p->owner ref on success so the bridging system can have<br>+ * control of when the channel is hung up.<br>+ */<br> if (ast_bridge_impart(bridge, c, replaces_chan, NULL,<br> AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {<br> ast_hangup(c);<br>- ast_channel_unref(c);<br> }<br>+ ao2_ref(bridge, -1);<br> } else {<br> ast_channel_move(replaces_chan, c);<br> ast_hangup(c);<br>- ast_channel_unref(c);<br> }<br>+ ast_channel_unref(c);<br> sip_pvt_lock(p);<br> return 0;<br> }<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/8731">change 8731</a>. To unsubscribe, 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/8731"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 15 </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I7edbed774314b55acf0067b2762bfe984ecaa9a4 </div>
<div style="display:none"> Gerrit-Change-Number: 8731 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Richard Mudgett <rmudgett@digium.com> </div>