[asterisk-bugs] [JIRA] (ASTERISK-27248) [patch]external_media_address and external_signaling_address don't always honor localnet

Walter Doekes (JIRA) noreply at issues.asterisk.org
Sat Sep 9 07:09:07 CDT 2017


    [ https://issues.asterisk.org/jira/browse/ASTERISK-27248?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=238615#comment-238615 ] 

Walter Doekes commented on ASTERISK-27248:
------------------------------------------

So, mea culpa, my fix did not work in the real world.

This bug was only apparent in my test case, and instead broke every one elses configuration.

**Testcase**

The checks had me confused because we were not checking the *remote address* but the *local SDP address*.

My test case ran on the local machine, like this:

- external_signaling_address=127.1.1.1
- external_media_address=127.2.2.2
- local_net=127.0.0.0/8
- call from ETH0IP to ETH0IP
- signaling IP would become 127.1.1.1 (OK)
- media IP would become ETH0IP (wrong, expected 127.2.2.2)

If I removed the local_net setting, the signaling and media IP would start to co-behave:

- signaling IP would be 127.1.1.1 (OK)
- media IP would be 127.2.2.2 (OK)

This, along with the weird semantics of DENY for "is in the list" confused me enough to oversee the fact that the local connection address was checked (correctly) in the case I altered.

Changing my testcase to:

- local_net=127.0.0.0/24 (instead of 127.0.0.0/8)
- call from 127.128.0.1 (isntead of from ETH0IP)

Now the SDP gets populated with 127.0.0.1 -- which falls in localnet -- and replaced like expected.

**Conclusion**

The immediate fix is to revert my fix. Although I'd prefer to document things a bit and amend the fix instead.

I'm not entirely convinced we should check our own supplied SDP IP to make the decision about whether to rewrite or not, but it's the best heuristic I see available. And like it is, it makes directmedia possible for Asterisken behind NAT.

> [patch]external_media_address and external_signaling_address don't always honor localnet
> ----------------------------------------------------------------------------------------
>
>                 Key: ASTERISK-27248
>                 URL: https://issues.asterisk.org/jira/browse/ASTERISK-27248
>             Project: Asterisk
>          Issue Type: Bug
>      Security Level: None
>          Components: Channels/chan_pjsip
>    Affects Versions: 13.17.1
>            Reporter: Walter Doekes
>         Attachments: ASTERISK-27248.patch
>
>
> Let's say I have this pjsip config:
> {noformat}
> external_signaling_address=127.1.1.1
> external_media_address=127.2.2.2
> {noformat}
> Then I want my outgoing invites to look like this:
> {noformat}
> INVITE sip:bob at DEST:9284;transport=UDP SIP/2.0
> Via: SIP/2.0/UDP 127.1.1.1:5060;rport;branch=z9hG4bKPjce5a5266-b624-4a52-b420-3648f073ec6d
> From: <sip:alice at SOURCE>;tag=904cc2dd-1f73-4d2c-b712-78c99761bc0f
> To: <sip:bob at SOURCE>
> Contact: <sip:asterisk at 127.1.1.1:5060>
> ...
> o=- 1018431938 1018431938 IN IP4 SOURCE
> s=Asterisk
> c=IN IP4 127.2.2.2
> {noformat}
> If I add an unrelated localnet setting, then it should not affect those values. For example:
> {noformat}
> local_net=127.255.255.255/32
> local_net=255.255.255.255/32
> {noformat}
> However, in Asterisk 13.17.1 it does differ, because of this code:
> {noformat}
>                 if (!transport_state->localnet
>                         || ast_apply_ha(transport_state->localnet, &addr) != AST_SENSE_ALLOW) {
>                         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));
>                 }
> {noformat}
> The ha struct stores the values in (default) "deny" order: if it's *not* found, then it's ALLOWed. If it *is* found, it returns DENY.
> Thus:
> {noformat}
> ast_apply_ha(transport_state->localnet, &addr) == AST_SENSE_ALLOW)
> {noformat}
> means: it's NOT in the local net
> and:
> {noformat}
> ast_apply_ha(transport_state->localnet, &addr) != AST_SENSE_ALLOW)
> {noformat}
> means: it IS in the local net.
> Logically, you would have it return DENY if it's NOT in the list, and ALLOW if it's in the list, but that's not how ast_apply_ha() works.
> If we check the latest 13.x, we see this:
> {noformat}
> $ wgrep . -B1 -A3 localnet.*SENSE
> {noformat}
> {noformat}
> ./res/res_pjsip_session.c-		if (!transport_state->localnet
> ./res/res_pjsip_session.c:			|| ast_apply_ha(transport_state->localnet, &addr) != AST_SENSE_ALLOW) {
> ./res/res_pjsip_session.c-			ast_debug(5, "Setting external media address to %s\n", ast_sockaddr_stringify_host(&transport_state->external_media_address));
> ./res/res_pjsip_session.c-			pj_strdup2(tdata->pool, &sdp->conn->addr, ast_sockaddr_stringify_host(&transport_state->external_media_address));
> ./res/res_pjsip_session.c-		}
> {noformat}
> DENY -> is local -> setting media to external because local??
> {noformat}
> ./res/res_pjsip_nat.c-		/* See if where we are sending this request is local or not, and if not that we can get a Contact URI to modify */
> ./res/res_pjsip_nat.c:		if (ast_apply_ha(transport_state->localnet, &addr) != AST_SENSE_ALLOW) {
> ./res/res_pjsip_nat.c-			ast_debug(5, "Request is being sent to local address, skipping NAT manipulation\n");
> ./res/res_pjsip_nat.c-			return PJ_SUCCESS;
> ./res/res_pjsip_nat.c-		}
> {noformat}
> DENY -> is local -> OK
> {noformat}
> ./res/res_pjsip_sdp_rtp.c-	if (transport_state->localnet
> ./res/res_pjsip_sdp_rtp.c:		&& ast_apply_ha(transport_state->localnet, &addr) == AST_SENSE_ALLOW) {
> ./res/res_pjsip_sdp_rtp.c-		return;
> ./res/res_pjsip_sdp_rtp.c-	}
> ./res/res_pjsip_sdp_rtp.c-	ast_debug(5, "Setting media address to %s\n", ast_sockaddr_stringify_host(&transport_state->external_media_address));
> {noformat}
> ALLOW -> is not local -> return -> not setting external IP because non-local??
> {noformat}
> ./res/res_pjsip_t38.c-	if (transport_state->localnet
> ./res/res_pjsip_t38.c:		&& ast_apply_ha(transport_state->localnet, &addr) == AST_SENSE_ALLOW) {
> ./res/res_pjsip_t38.c-		return;
> ./res/res_pjsip_t38.c-	}
> ./res/res_pjsip_t38.c-	ast_debug(5, "Setting media address to %s\n", ast_sockaddr_stringify_host(&transport_state->external_media_address));
> {noformat}
> ALLOW -> is not local -> return -> not setting external IP because non-local??
> It appears to me that 3/4 checks are wrong.
> I'd check the regression box, because a customer noticed this after 13.13.1, but I'm not sure how the changes interact. It appears that some of this was already broken before that change.



--
This message was sent by Atlassian JIRA
(v6.2#6252)



More information about the asterisk-bugs mailing list