Skip to content
Snippets Groups Projects
Commit 1d40faeb authored by David Vossel's avatar David Vossel
Browse files

contact header port ignored transport when using externip

This patch adds support for TCP/TLS in the Contact header when using
NAT, specifically externip or externhost. The original issue was that
Asterisk sent 5060 as the port in the contact header whether TLS was
used or not. Additionally, this patch adds 2 config options to sip.conf,
specifically externtcpport and externtlsport. This allows a user to
specify different external ports for TCP and TLS other than those used
internally, this is especially useful in in a PAT/port redirection setup.
Thanks to ebroad for reporting the issue and providing the patch!

(closes issue #15880)
Reported by: ebroad
Patches:
      portmap.patch uploaded by ebroad (license 878)
      externtXXport_v2.patch uploaded by ebroad (license 878)
Tested by: ebroad

Review: https://reviewboard.asterisk.org/r/392/



git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@222398 65c4cc65-6c06-0410-ace0-fbb531ad65f3
parent 4ac35a35
No related branches found
No related tags found
No related merge requests found
...@@ -2329,6 +2329,8 @@ static char externhost[MAXHOSTNAMELEN]; /*!< External host name */ ...@@ -2329,6 +2329,8 @@ static char externhost[MAXHOSTNAMELEN]; /*!< External host name */
static time_t externexpire; /*!< Expiration counter for re-resolving external host name in dynamic DNS */ static time_t externexpire; /*!< Expiration counter for re-resolving external host name in dynamic DNS */
static int externrefresh = 10; /*!< Refresh timer for DNS-based external address (dyndns) */ static int externrefresh = 10; /*!< Refresh timer for DNS-based external address (dyndns) */
static struct sockaddr_in stunaddr; /*!< stun server address */ static struct sockaddr_in stunaddr; /*!< stun server address */
uint16_t externtcpport = STANDARD_SIP_PORT; /*!< external tcp port */
uint16_t externtlsport = STANDARD_TLS_PORT; /*!< external tls port */
   
/*! \brief List of local networks /*! \brief List of local networks
* We store "localnet" addresses from the config file into an access list, * We store "localnet" addresses from the config file into an access list,
...@@ -3565,8 +3567,21 @@ static void ast_sip_ouraddrfor(struct in_addr *them, struct sockaddr_in *us, str ...@@ -3565,8 +3567,21 @@ static void ast_sip_ouraddrfor(struct in_addr *them, struct sockaddr_in *us, str
} }
externexpire = time(NULL) + externrefresh; externexpire = time(NULL) + externrefresh;
} }
if (externip.sin_addr.s_addr) if (externip.sin_addr.s_addr) {
*us = externip; *us = externip;
switch (p->socket.type) {
case SIP_TRANSPORT_TCP:
us->sin_port = htons(externtcpport);
break;
case SIP_TRANSPORT_TLS:
us->sin_port = htons(externtlsport);
break;
case SIP_TRANSPORT_UDP:
break; /* fall through */
default:
us->sin_port = htons(STANDARD_SIP_PORT); /* we should never get here */
}
}
else else
ast_log(LOG_WARNING, "stun failed\n"); ast_log(LOG_WARNING, "stun failed\n");
ast_debug(1, "Target address %s is not local, substituting externip\n", ast_debug(1, "Target address %s is not local, substituting externip\n",
...@@ -24926,6 +24941,8 @@ static int reload_config(enum channelreloadreason reason) ...@@ -24926,6 +24941,8 @@ static int reload_config(enum channelreloadreason reason)
default_primary_transport = 0; /*!< Reset default primary transport to zero here, default value later on */ default_primary_transport = 0; /*!< Reset default primary transport to zero here, default value later on */
ourport_tcp = STANDARD_SIP_PORT; ourport_tcp = STANDARD_SIP_PORT;
ourport_tls = STANDARD_TLS_PORT; ourport_tls = STANDARD_TLS_PORT;
externtcpport = 0;
externtlsport = 0;
bindaddr.sin_port = htons(STANDARD_SIP_PORT); bindaddr.sin_port = htons(STANDARD_SIP_PORT);
sip_cfg.srvlookup = DEFAULT_SRVLOOKUP; sip_cfg.srvlookup = DEFAULT_SRVLOOKUP;
global_tos_sip = DEFAULT_TOS_SIP; global_tos_sip = DEFAULT_TOS_SIP;
...@@ -25304,6 +25321,16 @@ static int reload_config(enum channelreloadreason reason) ...@@ -25304,6 +25321,16 @@ static int reload_config(enum channelreloadreason reason)
ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
externrefresh = 10; externrefresh = 10;
} }
} else if (!strcasecmp(v->name, "externtcpport")) {
if (!(externtcpport = port_str2int(v->value, 0))) {
ast_log(LOG_WARNING, "Invalid externtcpport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
externtcpport = ntohs(sip_tcp_desc.local_address.sin_port);
}
} else if (!strcasecmp(v->name, "externtlsport")) {
if (!(externtlsport = port_str2int(v->value, 0))) {
ast_log(LOG_WARNING, "Invalid externtlsport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
externtlsport = ntohs(sip_tls_desc.local_address.sin_port);
}
} else if (!strcasecmp(v->name, "allow")) { } else if (!strcasecmp(v->name, "allow")) {
int error = ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, TRUE); int error = ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, TRUE);
if (error) if (error)
...@@ -25473,7 +25500,14 @@ static int reload_config(enum channelreloadreason reason) ...@@ -25473,7 +25500,14 @@ static int reload_config(enum channelreloadreason reason)
if (default_transports == 0) { if (default_transports == 0) {
default_transports = default_primary_transport = SIP_TRANSPORT_UDP; default_transports = default_primary_transport = SIP_TRANSPORT_UDP;
} }
/* if not configured, set the defaults for externtcpport and externtlsport */
if (!externtcpport) {
externtcpport = ntohs(externip.sin_port); /* for consistency, default to the externip port */
}
if (!externtlsport) {
externtlsport = STANDARD_TLS_PORT;
}
/* Build list of authentication to various SIP realms, i.e. service providers */ /* Build list of authentication to various SIP realms, i.e. service providers */
for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
/* Format for authentication is auth = username:password@realm */ /* Format for authentication is auth = username:password@realm */
......
...@@ -643,6 +643,10 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls ...@@ -643,6 +643,10 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; externip = 12.34.56.78 ; use this address. ; externip = 12.34.56.78 ; use this address.
; externip = 12.34.56.78:9900 ; use this address and port. ; externip = 12.34.56.78:9900 ; use this address and port.
; externip = mynat.my.org:12600 ; Public address of my nat box. ; externip = mynat.my.org:12600 ; Public address of my nat box.
; externtcpport = 9900 ; The externally mapped tcp port, when Asterisk is behind a static NAT or PAT.
; ; externtcpport will default to the externip or externhost port if either one is set.
; externtlsport = 12600 ; The externally mapped tls port, when Asterisk is behind a static NAT or PAT.
; ; externtlsport port will default to the RFC designated port of 5061.
; ;
; b. "externhost = hostname[:port]" is similar to "externip" except ; b. "externhost = hostname[:port]" is similar to "externip" except
; that the hostname is looked up every "externrefresh" seconds ; that the hostname is looked up every "externrefresh" seconds
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment