From 680aba21ec1b91f4cd4061e652b8cd23356dfb9d Mon Sep 17 00:00:00 2001 From: Walter Doekes Date: Sun, 10 Sep 2017 13:17:27 +0200 Subject: [PATCH] res/res_pjsip: Fix localnet checks in pjsip, part 2. In 45744fc53, I mistakenly broke SDP media address rewriting by misinterpreting which address was checked in the localnet comparison. Instead of checking the remote peer address to decide whether we need media address rewriting, we check our local media address: if it's local, then we rewrite. This feels awkward, but works and even made directmedia work properly if you set local_net. (For the record: for local peers, the SDP media rewrite code is not called, so the comparison does no harm there.) ASTERISK-27248 #close Change-Id: I566be1c33f4d0a689567d451ed46bab9c3861d4f --- res/res_pjsip_sdp_rtp.c | 11 +++++++---- res/res_pjsip_session.c | 10 +++++++--- res/res_pjsip_t38.c | 11 +++++++---- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c index 9110a1c426..e095f06604 100644 --- a/res/res_pjsip_sdp_rtp.c +++ b/res/res_pjsip_sdp_rtp.c @@ -1807,7 +1807,7 @@ static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struc { RAII_VAR(struct ast_sip_transport_state *, transport_state, ast_sip_get_transport_state(ast_sorcery_object_get_id(transport)), ao2_cleanup); char host[NI_MAXHOST]; - struct ast_sockaddr addr = { { 0, } }; + struct ast_sockaddr our_sdp_addr = { { 0, } }; /* If the stream has been rejected there will be no connection line */ if (!stream->conn || !transport_state) { @@ -1815,10 +1815,13 @@ static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struc } ast_copy_pj_str(host, &stream->conn->addr, sizeof(host)); - ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID); + ast_sockaddr_parse(&our_sdp_addr, host, PARSE_PORT_FORBID); - /* Is the address within the SDP inside the same network? */ - if (ast_sip_transport_is_local(transport_state, &addr)) { + /* Reversed check here. We don't check the remote endpoint being + * in our local net, but whether our outgoing session IP is + * local. If it is not, we won't do rewriting. No localnet + * configured? Always rewrite. */ + if (ast_sip_transport_is_nonlocal(transport_state, &our_sdp_addr) && transport_state->localnet) { return; } ast_debug(5, "Setting media address to %s\n", ast_sockaddr_stringify_host(&transport_state->external_media_address)); diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index b9970244e7..64416a0636 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -3976,12 +3976,16 @@ static void session_outgoing_nat_hook(pjsip_tx_data *tdata, struct ast_sip_trans if (sdp->conn) { char host[NI_MAXHOST]; - struct ast_sockaddr addr = { { 0, } }; + struct ast_sockaddr our_sdp_addr = { { 0, } }; ast_copy_pj_str(host, &sdp->conn->addr, sizeof(host)); - ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID); + ast_sockaddr_parse(&our_sdp_addr, host, PARSE_PORT_FORBID); - if (ast_sip_transport_is_nonlocal(transport_state, &addr)) { + /* Reversed check here. We don't check the remote + * endpoint being in our local net, but whether our + * outgoing session IP is local. If it is, we'll do + * rewriting. No localnet configured? Always rewrite. */ + if (ast_sip_transport_is_local(transport_state, &our_sdp_addr) || !transport_state->localnet) { ast_debug(5, "Setting external media address to %s\n", ast_sockaddr_stringify_host(&transport_state->external_media_address)); pj_strdup2(tdata->pool, &sdp->conn->addr, ast_sockaddr_stringify_host(&transport_state->external_media_address)); } diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c index 6dec6ef5e2..48cbab37bd 100644 --- a/res/res_pjsip_t38.c +++ b/res/res_pjsip_t38.c @@ -952,7 +952,7 @@ static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struc { RAII_VAR(struct ast_sip_transport_state *, transport_state, ast_sip_get_transport_state(ast_sorcery_object_get_id(transport)), ao2_cleanup); char host[NI_MAXHOST]; - struct ast_sockaddr addr = { { 0, } }; + struct ast_sockaddr our_sdp_addr = { { 0, } }; /* If the stream has been rejected there will be no connection line */ if (!stream->conn || !transport_state) { @@ -960,10 +960,13 @@ static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struc } ast_copy_pj_str(host, &stream->conn->addr, sizeof(host)); - ast_sockaddr_parse(&addr, host, PARSE_PORT_FORBID); + ast_sockaddr_parse(&our_sdp_addr, host, PARSE_PORT_FORBID); - /* Is the address within the SDP inside the same network? */ - if (ast_sip_transport_is_local(transport_state, &addr)) { + /* Reversed check here. We don't check the remote endpoint being + * in our local net, but whether our outgoing session IP is + * local. If it is not, we won't do rewriting. No localnet + * configured? Always rewrite. */ + if (ast_sip_transport_is_nonlocal(transport_state, &our_sdp_addr) && transport_state->localnet) { return; } ast_debug(5, "Setting media address to %s\n", ast_sockaddr_stringify_host(&transport_state->external_media_address));