diff --git a/src/include/switch_stun.h b/src/include/switch_stun.h index f05a6e11df..54b03088e8 100644 --- a/src/include/switch_stun.h +++ b/src/include/switch_stun.h @@ -259,6 +259,15 @@ SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_priority(switch_stun_pa SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, switch_port_t *port, char *stunip, switch_port_t stunport, char **err, switch_memory_pool_t *pool); +/*! + \brief Perform a stun ip lookup + \param external_ip replaced with stun results + \param sourceip stun:, host: or an ip + \param external_pool the memory pool to use + \return SUCCESS or FAIL +*/ +SWITCH_DECLARE(switch_status_t) switch_stun_ip_lookup(char **external_ip, const char *sourceip, switch_memory_pool_t *external_pool); + /*! \brief Obtain the padded length of an attribute's value diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 7dc8336bd9..6ad57d2760 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -31,6 +31,7 @@ */ #include #include +#include /* Prototypes */ @@ -4824,7 +4825,7 @@ static switch_status_t parse_config(const char *cf) if (zstr(val)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid External RTP IP.\n"); } else { - profile->extrtpip = switch_core_strdup(profile->pool, val); + switch_stun_ip_lookup(&profile->extrtpip, val, profile->pool); } } else if (!strcasecmp(var, "debug")) { if (val) { diff --git a/src/switch_stun.c b/src/switch_stun.c index 6573d3eceb..f759a2607c 100644 --- a/src/switch_stun.c +++ b/src/switch_stun.c @@ -851,6 +851,79 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, return SWITCH_STATUS_FALSE; } +SWITCH_DECLARE(switch_status_t) switch_stun_ip_lookup(char **external_ip, const char *sourceip, switch_memory_pool_t *external_pool) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + char *stun_ip = NULL; + switch_port_t stun_port = (switch_port_t)SWITCH_STUN_DEFAULT_PORT; + char *p; + char ip_buf[256] = ""; + char *ip = NULL; + switch_port_t port = 0; + switch_memory_pool_t *local_pool = NULL; + char *error = ""; + + if (!sourceip || !external_pool) { + *external_ip = NULL; + goto end; + } + + ip = ip_buf; + + if (!strncasecmp(sourceip, "host:", 5)) { + status = (*external_ip = switch_stun_host_lookup(sourceip + 5, external_pool)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; + } + else if (!strncasecmp(sourceip, "stun:", 5)) { + + switch_core_new_memory_pool(&local_pool); + + stun_ip = switch_core_strdup(local_pool, sourceip + 5); + + switch_assert(stun_ip); + + if ((p = strchr(stun_ip, ':'))) { + int iport; + *p++ = '\0'; + iport = atoi(p); + if (iport > 0 && iport < 0xFFFF) { + stun_port = (switch_port_t)iport; + } + } + else { + p = stun_ip; + } + + switch_find_local_ip(ip_buf, sizeof(ip_buf), NULL, AF_INET); + + if (zstr(stun_ip)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! NO STUN SERVER\n"); + } + else { + if ((switch_stun_lookup(&ip, &port, stun_ip, stun_port, &error, local_pool)) == SWITCH_STATUS_SUCCESS && ip && port) { + *external_ip = switch_core_strdup(external_pool, ip); + status = SWITCH_STATUS_SUCCESS; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "External ip address detected using STUN: %s\n", ip); + } + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! [%s]\n", error); + } + } + + if (status != SWITCH_STATUS_SUCCESS) { + *external_ip = ""; + } + + switch_core_destroy_memory_pool(&local_pool); + } + else { + *external_ip = switch_core_strdup(external_pool, sourceip); + status = SWITCH_STATUS_SUCCESS; + } + +end: + + return status; +}