From c845cf2839777b556967af271530d6a6c040c177 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 19 Jan 2007 19:11:44 +0000 Subject: [PATCH] auto ip stuff git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4000 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- conf/freeswitch.xml | 10 +- src/include/switch_utils.h | 3 + .../endpoints/mod_dingaling/mod_dingaling.c | 8 +- src/mod/endpoints/mod_sofia/mod_sofia.c | 12 +- src/switch_utils.c | 172 +++++++++++++++++- 5 files changed, 185 insertions(+), 20 deletions(-) diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml index 4eb6a7b69e..77bb26850b 100644 --- a/conf/freeswitch.xml +++ b/conf/freeswitch.xml @@ -155,8 +155,8 @@ - - + + @@ -319,7 +319,7 @@ - + @@ -331,7 +331,7 @@ - + @@ -347,7 +347,7 @@ - + diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 80a600d6e6..8ef19bea70 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -79,6 +79,9 @@ SWITCH_DECLARE(apr_status_t) switch_socket_recvfrom(apr_sockaddr_t *from, apr_so !strcasecmp(expr, "true") ||\ atoi(expr))) ? SWITCH_TRUE : SWITCH_FALSE + +SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int family); + #define SWITCH_STATUS_IS_BREAK(x) (x == SWITCH_STATUS_BREAK || x == 730035 || x == 35) /*! diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index d358513104..686df5d2dd 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -97,6 +97,7 @@ static struct { switch_hash_t *profile_hash; int running; int handles; + char guess_ip[80]; } globals; struct mdl_profile { @@ -1800,9 +1801,9 @@ static void set_profile_val(struct mdl_profile *profile, char *var, char *val) } else if (!strcasecmp(var, "message")) { profile->message = switch_core_strdup(module_pool, val); } else if (!strcasecmp(var, "rtp-ip")) { - profile->ip = switch_core_strdup(module_pool, val); + profile->ip = switch_core_strdup(module_pool, strcasecmp(val, "auto") ? val : globals.guess_ip); } else if (!strcasecmp(var, "ext-rtp-ip")) { - profile->extip = switch_core_strdup(module_pool, val); + profile->extip = switch_core_strdup(module_pool, strcasecmp(val, "auto") ? val : globals.guess_ip); } else if (!strcasecmp(var, "server")) { profile->server = switch_core_strdup(module_pool, val); } else if (!strcasecmp(var, "rtp-timer-name")) { @@ -1933,7 +1934,8 @@ static switch_status_t load_config(void) memset(&globals, 0, sizeof(globals)); globals.running = 1; - + + switch_find_local_ip(globals.guess_ip, sizeof(globals.guess_ip), AF_INET); switch_core_hash_init(&globals.profile_hash, module_pool); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 5b9079c5ed..c402098033 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -177,6 +177,7 @@ static struct { uint32_t callid; int32_t running; switch_mutex_t *mutex; + char guess_ip[80]; } globals; typedef enum { @@ -4891,11 +4892,11 @@ static switch_status_t config_sofia(int reload) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invald option %s for VAD\n", val); } } else if (!strcasecmp(var, "ext-rtp-ip")) { - profile->extrtpip = switch_core_strdup(profile->pool, val); + profile->extrtpip = switch_core_strdup(profile->pool, strcasecmp(val, "auto") ? val : globals.guess_ip); } else if (!strcasecmp(var, "rtp-ip")) { - profile->rtpip = switch_core_strdup(profile->pool, val); + profile->rtpip = switch_core_strdup(profile->pool, strcasecmp(val, "auto") ? val : globals.guess_ip); } else if (!strcasecmp(var, "sip-ip")) { - profile->sipip = switch_core_strdup(profile->pool, val); + profile->sipip = switch_core_strdup(profile->pool, strcasecmp(val, "auto") ? val : globals.guess_ip); } else if (!strcasecmp(var, "sip-domain")) { profile->sipdomain = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "rtp-timer-name")) { @@ -4921,7 +4922,7 @@ static switch_status_t config_sofia(int reload) profile->pflags |= PFLAG_FULL_ID; } } else if (!strcasecmp(var, "ext-sip-ip")) { - profile->extsipip = switch_core_strdup(profile->pool, val); + profile->extsipip = switch_core_strdup(profile->pool, strcasecmp(val, "auto") ? val : globals.guess_ip); } else if (!strcasecmp(var, "bitpacking")) { if (!strcasecmp(val, "aal2")) { profile->codec_flags = SWITCH_CODEC_FLAG_AAL2; @@ -5495,7 +5496,8 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod memset(&globals, 0, sizeof(globals)); switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool); - + + switch_find_local_ip(globals.guess_ip, sizeof(globals.guess_ip), AF_INET); if (switch_event_bind((char *) modname, SWITCH_EVENT_CUSTOM, MULTICAST_EVENT, event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); diff --git a/src/switch_utils.c b/src/switch_utils.c index 1e82035236..beb49b3161 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -33,8 +33,163 @@ #include #include #include +#ifndef WIN32 +#include +#endif +static char *get_addr(char *buf, switch_size_t len, struct in_addr *in); + +SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int family) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + char *base; + +#ifdef WIN32 + SOCKET tmp_socket; + SOCKADDR_STORAGE l_address; + int l_address_len; + struct addrinfo *address_info; +#else +#ifdef __APPLE_CC__ + int ilen; +#else + unsigned int ilen; +#endif + int tmp_socket = -1, on = 1; + char abuf[25] = ""; +#endif + + switch_copy_string(buf, "127.0.0.1", len); + + switch(family) { + case AF_INET: + base = "82.45.148.209"; + break; + case AF_INET6: + base = "52.2d.94.d1"; + break; + } +#ifdef WIN32 + tmp_socket = socket(family, SOCK_DGRAM, 0); + + getaddrinfo(base, NULL, NULL, &address_info); + + if (WSAIoctl(tmp_socket, + SIO_ROUTING_INTERFACE_QUERY, + address_info->ai_addr, + address_info->ai_addrlen, + &l_address, + sizeof(l_address), + &l_address_len, + NULL, + NULL)) { + + closesocket(tmp_socket); + freeaddrinfo(address_info); + return status; + } + + closesocket(tmp_socket); + freeaddrinfo(address_info); + + if(!getnameinfo((const struct sockaddr*)&l_address, + l_address_len, + buf, + len, + NULL, + 0, + NI_NUMERICHOST)) { + + status = SWITCH_STATUS_SUCCESS; + + } + +#else + + switch(family) { + case AF_INET: + { + struct sockaddr_in iface_out; + struct sockaddr_in remote; + memset (&remote, 0, sizeof (struct sockaddr_in)); + + remote.sin_family = AF_INET; + remote.sin_addr.s_addr = inet_addr (base); + remote.sin_port = htons (4242); + + memset (&iface_out, 0, sizeof (iface_out)); + tmp_socket = socket (AF_INET, SOCK_DGRAM, 0); + + if (setsockopt (tmp_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) == -1) { + goto doh; + } + + if (connect (tmp_socket, (struct sockaddr *) &remote, sizeof (struct sockaddr_in)) == -1) { + goto doh; + } + + ilen = sizeof (iface_out); + if (getsockname (tmp_socket, (struct sockaddr *) &iface_out, &ilen) == -1) { + goto doh; + } + + if (iface_out.sin_addr.s_addr == 0) { + goto doh; + } + + switch_copy_string(buf, get_addr(abuf, sizeof(abuf), &iface_out.sin_addr), len); + status = SWITCH_STATUS_SUCCESS; + } + break; + case AF_INET6: + { + struct sockaddr_in6 iface_out; + struct sockaddr_in6 remote; + memset (&remote, 0, sizeof (struct sockaddr_in6)); + + remote.sin6_family = AF_INET6; + inet_pton (AF_INET6, buf, &remote.sin6_addr); + remote.sin6_port = htons (4242); + + memset (&iface_out, 0, sizeof (iface_out)); + tmp_socket = socket (AF_INET6, SOCK_DGRAM, 0); + + if (setsockopt (tmp_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) == -1) { + goto doh; + } + + if (connect (tmp_socket, (struct sockaddr *) &remote, sizeof (struct sockaddr_in)) == -1) { + goto doh; + } + + ilen = sizeof (iface_out); + if (getsockname (tmp_socket, (struct sockaddr *) &iface_out, &ilen) == -1) { + goto doh; + } + + if (iface_out.sin6_addr.s6_addr == 0) { + goto doh; + } + + inet_ntop (AF_INET6, (const void *) &iface_out.sin6_addr, buf, len - 1); + status = SWITCH_STATUS_SUCCESS; + } + break; + } + + + doh: + if (tmp_socket > 0) { + close (tmp_socket); + tmp_socket = -1; + } + +#endif + + return status; + +} SWITCH_DECLARE(int) switch_perform_regex(char *field, char *expression, pcre **new_re, int *ovector, uint32_t olen) { @@ -190,15 +345,13 @@ SWITCH_DECLARE(char *) switch_priority_name(switch_priority_t priority) static char RFC2833_CHARS[] = "0123456789*#ABCDF"; - - -SWITCH_DECLARE(char *) switch_get_addr(char *buf, switch_size_t len, switch_sockaddr_t *in) +static char *get_addr(char *buf, switch_size_t len, struct in_addr *in) { uint8_t x, *i; char *p = buf; - i = (uint8_t *) &in->sa.sin.sin_addr; + i = (uint8_t *) in; memset(buf, 0, len); for(x =0; x < 4; x++) { @@ -208,9 +361,14 @@ SWITCH_DECLARE(char *) switch_get_addr(char *buf, switch_size_t len, switch_sock return buf; } +SWITCH_DECLARE(char *) switch_get_addr(char *buf, switch_size_t len, switch_sockaddr_t *in) +{ + return get_addr(buf, len, &in->sa.sin.sin_addr); +} + SWITCH_DECLARE(apr_status_t) switch_socket_recvfrom(apr_sockaddr_t *from, apr_socket_t *sock, - apr_int32_t flags, char *buf, - apr_size_t *len) + apr_int32_t flags, char *buf, + apr_size_t *len) { apr_status_t r; @@ -355,7 +513,7 @@ SWITCH_DECLARE(char *) switch_cut_path(char *in) } SWITCH_DECLARE(switch_status_t) switch_socket_create_pollfd(switch_pollfd_t *poll, switch_socket_t *sock, - switch_int16_t flags, switch_memory_pool_t *pool) + switch_int16_t flags, switch_memory_pool_t *pool) { switch_pollset_t *pollset;