<p>Friendly Automation <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/12876">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Benjamin Keith Ford: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved
  Friendly Automation: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">chan_pjsip: Relock correct channel during "fax" redirect.<br><br>When fax detection occurs on an outbound PJSIP channel the<br>redirect operation will result in a masquerade occurring and<br>the underlying channel on the session changing. The code<br>incorrectly relocked the new channel instead of the old<br>channel when returning. This resulted in the new channel<br>being locked indefinitely. The code now always acts on the<br>expected channel.<br><br>ASTERISK-28538<br><br>Change-Id: I2b2e60d07e74383ae7e90d752c036c4b02d6b3a3<br>---<br>M channels/chan_pjsip.c<br>1 file changed, 24 insertions(+), 14 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c</span><br><span>index 8ab1549..627470e 100644</span><br><span>--- a/channels/chan_pjsip.c</span><br><span>+++ b/channels/chan_pjsip.c</span><br><span>@@ -749,7 +749,8 @@</span><br><span> }</span><br><span> </span><br><span> /*! \brief Internal helper function called when CNG tone is detected */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_frame *chan_pjsip_cng_tone_detected(struct ast_sip_session *session, struct ast_frame *f)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_frame *chan_pjsip_cng_tone_detected(struct ast_channel *ast, struct ast_sip_session *session,</span><br><span style="color: hsl(120, 100%, 40%);">+        struct ast_frame *f)</span><br><span> {</span><br><span>    const char *target_context;</span><br><span>  int exists;</span><br><span>@@ -765,11 +766,11 @@</span><br><span>  }</span><br><span> </span><br><span>        /* If already executing in the fax extension don't do anything */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!strcmp(ast_channel_exten(session->channel), "fax")) {</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!strcmp(ast_channel_exten(ast), "fax")) {</span><br><span>              return f;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   target_context = S_OR(ast_channel_macrocontext(session->channel), ast_channel_context(session->channel));</span><br><span style="color: hsl(120, 100%, 40%);">+       target_context = S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast));</span><br><span> </span><br><span>  /*</span><br><span>    * We need to unlock the channel here because ast_exists_extension has the</span><br><span>@@ -778,25 +779,30 @@</span><br><span>    *</span><br><span>    * ast_async_goto() has its own restriction on not holding the channel lock.</span><br><span>          */</span><br><span style="color: hsl(0, 100%, 40%);">-     ast_channel_unlock(session->channel);</span><br><span style="color: hsl(120, 100%, 40%);">+      ast_channel_unlock(ast);</span><br><span>     ast_frfree(f);</span><br><span>       f = &ast_null_frame;</span><br><span style="color: hsl(0, 100%, 40%);">-        exists = ast_exists_extension(session->channel, target_context, "fax", 1,</span><br><span style="color: hsl(0, 100%, 40%);">-          S_COR(ast_channel_caller(session->channel)->id.number.valid,</span><br><span style="color: hsl(0, 100%, 40%);">-                      ast_channel_caller(session->channel)->id.number.str, NULL));</span><br><span style="color: hsl(120, 100%, 40%);">+    exists = ast_exists_extension(ast, target_context, "fax", 1,</span><br><span style="color: hsl(120, 100%, 40%);">+                S_COR(ast_channel_caller(ast)->id.number.valid,</span><br><span style="color: hsl(120, 100%, 40%);">+                    ast_channel_caller(ast)->id.number.str, NULL));</span><br><span>   if (exists) {</span><br><span>                ast_verb(2, "Redirecting '%s' to fax extension due to CNG detection\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                       ast_channel_name(session->channel));</span><br><span style="color: hsl(0, 100%, 40%);">-         pbx_builtin_setvar_helper(session->channel, "FAXEXTEN", ast_channel_exten(session->channel));</span><br><span style="color: hsl(0, 100%, 40%);">-           if (ast_async_goto(session->channel, target_context, "fax", 1)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        ast_channel_name(ast));</span><br><span style="color: hsl(120, 100%, 40%);">+               pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));</span><br><span style="color: hsl(120, 100%, 40%);">+         if (ast_async_goto(ast, target_context, "fax", 1)) {</span><br><span>                       ast_log(LOG_ERROR, "Failed to async goto '%s' into fax extension in '%s'\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                          ast_channel_name(session->channel), target_context);</span><br><span style="color: hsl(120, 100%, 40%);">+                               ast_channel_name(ast), target_context);</span><br><span>              }</span><br><span>    } else {</span><br><span>             ast_log(LOG_NOTICE, "FAX CNG detected on '%s' but no fax extension in '%s'\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                        ast_channel_name(session->channel), target_context);</span><br><span style="color: hsl(120, 100%, 40%);">+                       ast_channel_name(ast), target_context);</span><br><span>      }</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_channel_lock(session->channel);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* It's possible for a masquerade to have occurred when doing the ast_async_goto resulting in</span><br><span style="color: hsl(120, 100%, 40%);">+      * the channel on the session having changed. Since we need to return with the original channel</span><br><span style="color: hsl(120, 100%, 40%);">+        * locked we lock the channel that was passed in and not session->channel.</span><br><span style="color: hsl(120, 100%, 40%);">+  */</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_channel_lock(ast);</span><br><span> </span><br><span>   return f;</span><br><span> }</span><br><span>@@ -895,7 +901,11 @@</span><br><span>                        if (f->subclass.integer == 'f') {</span><br><span>                                 ast_debug(3, "Channel driver fax CNG detected on %s\n",</span><br><span>                                    ast_channel_name(ast));</span><br><span style="color: hsl(0, 100%, 40%);">-                         f = chan_pjsip_cng_tone_detected(session, f);</span><br><span style="color: hsl(120, 100%, 40%);">+                         f = chan_pjsip_cng_tone_detected(ast, session, f);</span><br><span style="color: hsl(120, 100%, 40%);">+                            /* When chan_pjsip_cng_tone_detected returns it is possible for the</span><br><span style="color: hsl(120, 100%, 40%);">+                            * channel pointed to by ast and by session->channel to differ due to a</span><br><span style="color: hsl(120, 100%, 40%);">+                             * masquerade. It's best not to touch things after this.</span><br><span style="color: hsl(120, 100%, 40%);">+                           */</span><br><span>                  } else {</span><br><span>                             ast_debug(3, "* Detected inband DTMF '%c' on '%s'\n", f->subclass.integer,</span><br><span>                                      ast_channel_name(ast));</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/12876">change 12876</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/+/12876"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: I2b2e60d07e74383ae7e90d752c036c4b02d6b3a3 </div>
<div style="display:none"> Gerrit-Change-Number: 12876 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Benjamin Keith Ford <bford@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>