From e6dc28b78fbb8ae606daf1700a09772401ca063e Mon Sep 17 00:00:00 2001
From: Matt Jordan <mjordan@digium.com>
Date: Thu, 16 Mar 2017 10:39:00 -0500
Subject: [PATCH] res/res_pjsip_session: Only check localnet if it is defined

If local_net is not defined on a transport, transport_state->localnet
will be NULL. ast_apply_ha will, be default, return AST_SENSE_ALLOW in
this case, causing the external_media_address, if set, to be skipped.

This patch causes us to only check if we are sending within a network if
local_net is defined.

ASTERISK-26879 #close

Change-Id: Ib661c31a954cabc9c99f1f25c9c9a5c5b82cbbfb
---
 res/res_pjsip_nat.c     | 43 +++++++++++++++++++++--------------------
 res/res_pjsip_sdp_rtp.c |  5 +++--
 res/res_pjsip_session.c |  5 ++++-
 res/res_pjsip_t38.c     |  5 +++--
 4 files changed, 32 insertions(+), 26 deletions(-)

diff --git a/res/res_pjsip_nat.c b/res/res_pjsip_nat.c
index a855298b2f..a26180bc0b 100644
--- a/res/res_pjsip_nat.c
+++ b/res/res_pjsip_nat.c
@@ -262,32 +262,33 @@ static pj_status_t nat_on_tx_message(pjsip_tx_data *tdata)
 		return PJ_SUCCESS;
 	}
 
-	if ( !transport_state->localnet || 	ast_sockaddr_isnull(&transport_state->external_address)) {
-		return PJ_SUCCESS;
-	}
-
-	ast_sockaddr_parse(&addr, tdata->tp_info.dst_name, PARSE_PORT_FORBID);
-	ast_sockaddr_set_port(&addr, tdata->tp_info.dst_port);
+	if (transport_state->localnet) {
+		ast_sockaddr_parse(&addr, tdata->tp_info.dst_name, PARSE_PORT_FORBID);
+		ast_sockaddr_set_port(&addr, tdata->tp_info.dst_port);
 
-	/* See if where we are sending this request is local or not, and if not that we can get a Contact URI to modify */
-	if (ast_apply_ha(transport_state->localnet, &addr) != AST_SENSE_ALLOW) {
-		return PJ_SUCCESS;
+		/* See if where we are sending this request is local or not, and if not that we can get a Contact URI to modify */
+		if (ast_apply_ha(transport_state->localnet, &addr) != AST_SENSE_ALLOW) {
+			ast_debug(5, "Request is being sent to local address, skipping NAT manipulation\n");
+			return PJ_SUCCESS;
+		}
 	}
 
-	/* Update the contact header with the external address */
-	if (uri || (uri = nat_get_contact_sip_uri(tdata))) {
-		pj_strdup2(tdata->pool, &uri->host, ast_sockaddr_stringify_host(&transport_state->external_address));
-		if (transport->external_signaling_port) {
-			uri->port = transport->external_signaling_port;
-			ast_debug(4, "Re-wrote Contact URI port to %d\n", uri->port);
+	if (!ast_sockaddr_isnull(&transport_state->external_address)) {
+		/* Update the contact header with the external address */
+		if (uri || (uri = nat_get_contact_sip_uri(tdata))) {
+			pj_strdup2(tdata->pool, &uri->host, ast_sockaddr_stringify_host(&transport_state->external_address));
+			if (transport->external_signaling_port) {
+				uri->port = transport->external_signaling_port;
+				ast_debug(4, "Re-wrote Contact URI port to %d\n", uri->port);
+			}
 		}
-	}
 
-	/* Update the via header if relevant */
-	if ((tdata->msg->type == PJSIP_REQUEST_MSG) && (via || (via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL)))) {
-		pj_strdup2(tdata->pool, &via->sent_by.host, ast_sockaddr_stringify_host(&transport_state->external_address));
-		if (transport->external_signaling_port) {
-			via->sent_by.port = transport->external_signaling_port;
+		/* Update the via header if relevant */
+		if ((tdata->msg->type == PJSIP_REQUEST_MSG) && (via || (via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL)))) {
+			pj_strdup2(tdata->pool, &via->sent_by.host, ast_sockaddr_stringify_host(&transport_state->external_address));
+			if (transport->external_signaling_port) {
+				via->sent_by.port = transport->external_signaling_port;
+			}
 		}
 	}
 
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index 9f39256e56..75dc83929d 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -1473,10 +1473,11 @@ static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struc
 	ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID);
 
 	/* Is the address within the SDP inside the same network? */
-	if (ast_apply_ha(transport_state->localnet, &addr) == AST_SENSE_ALLOW) {
+	if (transport_state->localnet
+		&& ast_apply_ha(transport_state->localnet, &addr) == AST_SENSE_ALLOW) {
 		return;
 	}
-
+	ast_debug(5, "Setting media address to %s\n", transport->external_media_address);
 	pj_strdup2(tdata->pool, &stream->conn->addr, transport->external_media_address);
 }
 
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index ad9670cd12..609d08dc06 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -3148,7 +3148,10 @@ static void session_outgoing_nat_hook(pjsip_tx_data *tdata, struct ast_sip_trans
 		ast_copy_pj_str(host, &sdp->conn->addr, sizeof(host));
 		ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID);
 
-		if (ast_apply_ha(transport_state->localnet, &addr) != AST_SENSE_ALLOW) {
+		if (!transport_state->localnet
+			|| (transport_state->localnet
+				&& ast_apply_ha(transport_state->localnet, &addr) == AST_SENSE_ALLOW)) {
+			ast_debug(5, "Setting external media address to %s\n", transport->external_media_address);
 			pj_strdup2(tdata->pool, &sdp->conn->addr, transport->external_media_address);
 		}
 	}
diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c
index 79dc9c3247..bae4ff1dca 100644
--- a/res/res_pjsip_t38.c
+++ b/res/res_pjsip_t38.c
@@ -867,10 +867,11 @@ static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struc
 	ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID);
 
 	/* Is the address within the SDP inside the same network? */
-	if (ast_apply_ha(transport_state->localnet, &addr) == AST_SENSE_ALLOW) {
+	if (transport_state->localnet
+		&& ast_apply_ha(transport_state->localnet, &addr) == AST_SENSE_ALLOW) {
 		return;
 	}
-
+	ast_debug(5, "Setting media address to %s\n", transport->external_media_address);
 	pj_strdup2(tdata->pool, &stream->conn->addr, transport->external_media_address);
 }
 
-- 
GitLab