Summary:ASTERISK-11011: Asterisk TRUNK version - problem with NAT, ignoring localnet, ..
Reporter:Pavol Luptak (wilder)Labels:
Date Opened:2007-12-11 13:06:37.000-0600Date Closed:2007-12-11 15:55:46.000-0600
Versions:Frequency of
Description:This bug affects only Asterisk TRUNK, SIP/TCP-TLS and related projects (the latest stable Asterisk 1.4.15 and Asterisk 1.2.x are not affected).

The problem is appeared when my SIP client with the IP address from "localnet"
subnet is connecting to my Asterisk server that is also in the "localnet"
In this situation Asterisk ignores "localnet" parameter and remaps
internal IP addresses in the SIP frames with "externhost" which is incorrect.
Asterisk 1.4.15 (and lower) does remapping only if the hosts are outside
of localnet subnet.

After hours of debugging/analysing I have revealed the bug in the function
ast_sip_ouraddrfor (in chan_sip.c) - yes, this function has been completely
rewritten since stable 1.4.15:

static void ast_sip_ouraddrfor(struct in_addr *them, struct sockaddr_in *us)
       struct sockaddr_in theirs;
       /* Set want_remap to non-zero if we want to remap 'us' to an externally
        * reachable IP address and port. This is done if:
        * 1. we have a localaddr list (containing 'internal' addresses marked
        *    as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them,
        *    and AST_SENSE_ALLOW on 'external' ones);
        * 2. either stunaddr or externip is set, so we know what to use as the
        *    externally visible address;
        * 3. the remote address, 'them', is external;
        * 4. the address returned by ast_ouraddrfor() is 'internal'
        *    when passed to ast_apply_ha() so it does need to be remapped.
        *    This fourth condition is checked later.
       int want_remap = localaddr &&
               (externip.sin_addr.s_addr || stunaddr.sin_addr.s_addr) &&
               ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ;

       *us = internip;         /* starting guess for the internal address */
       /* now ask the system what would it use to talk to 'them' */
       ast_ouraddrfor(them, &us->sin_addr);
       theirs.sin_addr = *them;

as you can see, the variable want_remap is inicialized before setting
theirs.sin_addr variable which is wrong. I only changed the order of the
inicialization: and now it works correctly.
Comments:By: Jason Parker (jparker) 2007-12-11 15:53:24.000-0600

Please do not post patches in description or notes.  You must attach them so that they can be tracked.

I will, however, be able to fix this based on your description of init order.

By: Digium Subversion (svnbot) 2007-12-11 15:55:45.000-0600

Repository: asterisk
Revision: 92421

U   trunk/channels/chan_sip.c

r92421 | qwell | 2007-12-11 15:55:45 -0600 (Tue, 11 Dec 2007) | 4 lines

We need to set the address we want to match against before we actually do the match..

Closes issue ASTERISK-11011.