<p>George Joseph <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/10531">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Joshua Colp: Looks good to me, but someone else must approve; Verified
George Joseph: Looks good to me, approved; Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res/res_pjsip_nat: Fix logic for REINVITES<br><br>The presence of Record-Route in re-invites is optional, thus it is<br>important to make sure the dialog doesn't have a routset before<br>rewriting the contact header.<br><br>ASTERISK-28129 #close<br><br>Change-Id: Ic8ceb54ccfc93f7e315e476c514a2c777f2da7dc<br>---<br>M res/res_pjsip_nat.c<br>1 file changed, 68 insertions(+), 8 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/res/res_pjsip_nat.c b/res/res_pjsip_nat.c</span><br><span>index 370004a..a0161d7 100644</span><br><span>--- a/res/res_pjsip_nat.c</span><br><span>+++ b/res/res_pjsip_nat.c</span><br><span>@@ -45,10 +45,42 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Update the Record-Route headers in the request or response and in the dialog</span><br><span style="color: hsl(120, 100%, 40%);">+ * object if exists.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * When NAT is in use, the address of the next hop in the SIP may be incorrect.</span><br><span style="color: hsl(120, 100%, 40%);">+ * To address this asterisk uses two strategies in parallel:</span><br><span style="color: hsl(120, 100%, 40%);">+ * 1. intercept the messages at the transaction level and rewrite the</span><br><span style="color: hsl(120, 100%, 40%);">+ * messages before arriving at the dialog layer</span><br><span style="color: hsl(120, 100%, 40%);">+ * 2. after the application processing, update the dialog object with the</span><br><span style="color: hsl(120, 100%, 40%);">+ * correct information</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * The first strategy has a limitation that the SIP message may not have all</span><br><span style="color: hsl(120, 100%, 40%);">+ * the information required to determine if the next hop is in the route set</span><br><span style="color: hsl(120, 100%, 40%);">+ * or in the contact. Causing risk that asterisk will update the Contact on</span><br><span style="color: hsl(120, 100%, 40%);">+ * receipt of an in-dialog message despite there being a route set saved in</span><br><span style="color: hsl(120, 100%, 40%);">+ * the dialog.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * The second strategy has a limitation that not all UAC layers have interfaces</span><br><span style="color: hsl(120, 100%, 40%);">+ * available to invoke this module after dialog creation. (pjsip_sesion does</span><br><span style="color: hsl(120, 100%, 40%);">+ * but pjsip_pubsub does not), thus this strategy can't update the dialog in</span><br><span style="color: hsl(120, 100%, 40%);">+ * all cases needed.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * The ideal solution would be to implement an "incomming_request" event</span><br><span style="color: hsl(120, 100%, 40%);">+ * in pubsub module that can then pass the dialog object to this module</span><br><span style="color: hsl(120, 100%, 40%);">+ * on SUBSCRIBE, this module then should add itself as a listener to the dialog</span><br><span style="color: hsl(120, 100%, 40%);">+ * for the subsequent requests and responses & then be able to properly update</span><br><span style="color: hsl(120, 100%, 40%);">+ * the dialog object for all required events.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int rewrite_route_set(pjsip_rx_data *rdata, pjsip_dialog *dlg)</span><br><span> {</span><br><span> pjsip_rr_hdr *rr = NULL;</span><br><span> pjsip_sip_uri *uri;</span><br><span style="color: hsl(120, 100%, 40%);">+ int res = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ int ignore_rr = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int pubsub = 0;</span><br><span> </span><br><span> if (rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG) {</span><br><span> pjsip_hdr *iter;</span><br><span>@@ -60,21 +92,49 @@</span><br><span> }</span><br><span> } else if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_register_method)) {</span><br><span> rr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_RECORD_ROUTE, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Record-Route header has no meaning in REGISTER requests</span><br><span style="color: hsl(120, 100%, 40%);">+ * and should be ignored</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ ignore_rr = 1;</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%);">+ if (!pjsip_method_cmp(&rdata->msg_info.cseq->method, &pjsip_subscribe_method) ||</span><br><span style="color: hsl(120, 100%, 40%);">+ !pjsip_method_cmp(&rdata->msg_info.cseq->method, &pjsip_notify_method)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /**</span><br><span style="color: hsl(120, 100%, 40%);">+ * There is currently no good way to get the dlg object for a pubsub dialog</span><br><span style="color: hsl(120, 100%, 40%);">+ * so we will just look at the rr & contact of the current message and</span><br><span style="color: hsl(120, 100%, 40%);">+ * hope for the best</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ pubsub = 1;</span><br><span> }</span><br><span> </span><br><span> if (rr) {</span><br><span> uri = pjsip_uri_get_uri(&rr->name_addr);</span><br><span> rewrite_uri(rdata, uri);</span><br><span style="color: hsl(0, 100%, 40%);">- if (dlg && !pj_list_empty(&dlg->route_set) && !dlg->route_set_frozen) {</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip_routing_hdr *route = dlg->route_set.next;</span><br><span style="color: hsl(0, 100%, 40%);">- uri = pjsip_uri_get_uri(&route->name_addr);</span><br><span style="color: hsl(0, 100%, 40%);">- rewrite_uri(rdata, uri);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ res = 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (dlg && !pj_list_empty(&dlg->route_set) && !dlg->route_set_frozen) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip_routing_hdr *route = dlg->route_set.next;</span><br><span style="color: hsl(120, 100%, 40%);">+ uri = pjsip_uri_get_uri(&route->name_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+ rewrite_uri(rdata, uri);</span><br><span style="color: hsl(120, 100%, 40%);">+ res = 0;</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%);">+ if (!dlg && !rr && !ignore_rr && !pubsub && rdata->msg_info.to->tag.slen){</span><br><span style="color: hsl(120, 100%, 40%);">+ /**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Even if this message doesn't have any route headers</span><br><span style="color: hsl(120, 100%, 40%);">+ * the dialog may, so wait until a later invocation that</span><br><span style="color: hsl(120, 100%, 40%);">+ * has a dialog reference to make sure there isn't a</span><br><span style="color: hsl(120, 100%, 40%);">+ * previously saved routset in the dialog before deciding</span><br><span style="color: hsl(120, 100%, 40%);">+ * the contact needs to be modified</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ res = 0;</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%);">+ return res;</span><br><span> }</span><br><span> </span><br><span> static int rewrite_contact(pjsip_rx_data *rdata, pjsip_dialog *dlg)</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/10531">change 10531</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/10531"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ic8ceb54ccfc93f7e315e476c514a2c777f2da7dc </div>
<div style="display:none"> Gerrit-Change-Number: 10531 </div>
<div style="display:none"> Gerrit-PatchSet: 7 </div>
<div style="display:none"> Gerrit-Owner: Torrey Searle <tsearle@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 (1000185) </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>