From: Andrey Volk Date: Fri, 12 Jun 2026 13:13:47 +0000 (+0300) Subject: [Core] switch_sockaddr_info_get() will not resolve if the hostname is an IP address... X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=be554e4a0852ede27902bd03dd6efbd177902661;p=thirdparty%2Ffreeswitch.git [Core] switch_sockaddr_info_get() will not resolve if the hostname is an IP address. Add new switch_is_ip_address() API. Add a unit-test. (#3055) --- diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index a0c91e6384..68667ee477 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -1519,6 +1519,13 @@ SWITCH_DECLARE(const char *) switch_memory_usage_stream(switch_stream_handle_t * **/ SWITCH_DECLARE(int) switch_rand(void); +/*! + * \brief Check if a hostname is a valid IP address (IPv4 or IPv6) + * \param hostname The hostname to check + * \return 1 if a valid IP address, 0 - otherwise + */ +SWITCH_DECLARE(int) switch_is_ip_address(const char *hostname); + SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/switch_apr.c b/src/switch_apr.c index 60660d6e2e..09e4ba51e4 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -841,6 +841,10 @@ SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, s SWITCH_DECLARE(switch_status_t) switch_sockaddr_info_get(switch_sockaddr_t ** sa, const char *hostname, int32_t family, switch_port_t port, int32_t flags, switch_memory_pool_t *pool) { + if (!zstr(hostname) && switch_is_ip_address(hostname)) { + return switch_sockaddr_new(sa, hostname, port, pool); + } + return fspr_sockaddr_info_get(sa, hostname, family, port, flags, pool); } diff --git a/src/switch_utils.c b/src/switch_utils.c index dc855c8def..854659ab4a 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -4888,6 +4888,24 @@ SWITCH_DECLARE(int) switch_rand(void) #endif } +SWITCH_DECLARE(int) switch_is_ip_address(const char *hostname) +{ + struct sockaddr_in sa; + struct sockaddr_in6 sa6; + + if (!hostname) return 0; + + if (inet_pton(AF_INET, hostname, &(sa.sin_addr)) == 1) { + return 1; /* It is a valid IPv4 address */ + } + + if (inet_pton(AF_INET6, hostname, &(sa6.sin6_addr)) == 1) { + return 1; /* It is a valid IPv6 address */ + } + + return 0; /* Not a valid IPv4 or IPv6 address */ +} + /* For Emacs: * Local Variables: * mode:c diff --git a/tests/unit/switch_core.c b/tests/unit/switch_core.c index 6b4ba12e04..096c8d014a 100644 --- a/tests/unit/switch_core.c +++ b/tests/unit/switch_core.c @@ -72,6 +72,24 @@ FST_CORE_BEGIN("./conf") } FST_TEARDOWN_END() + FST_TEST_BEGIN(test_is_ip_address) + { + const char *test_ips[] = { + "192.168.1.1", // Valid IPv4 + "2001:db8::ff00:42:8329", // Valid IPv6 + "www.google.com", // Hostname + "not.an.ip.address", + NULL + }; + + fst_check_int_equals(switch_is_ip_address(test_ips[0]), 1); + fst_check_int_equals(switch_is_ip_address(test_ips[1]), 1); + fst_check_int_equals(switch_is_ip_address(test_ips[2]), 0); + fst_check_int_equals(switch_is_ip_address(test_ips[3]), 0); + fst_check_int_equals(switch_is_ip_address(test_ips[4]), 0); + } + FST_TEST_END(); + FST_TEST_BEGIN(test_switch_regex) { switch_regex_match_t *match_data = NULL;