mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-14 08:05:37 +00:00
[Core] switch_core_port_allocator: Replace getaddrinfo() (may get stuck) with switch_sockaddr_new() and fix IPv6.
This commit is contained in:
parent
040416b8db
commit
913551315b
@ -1145,6 +1145,8 @@ SWITCH_DECLARE(switch_status_t) switch_sockaddr_info_get(switch_sockaddr_t ** sa
|
|||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, switch_memory_pool_t *pool);
|
SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, switch_memory_pool_t *pool);
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_sockaddr_new(switch_sockaddr_t ** sa, const char *ip, switch_port_t port, switch_memory_pool_t *pool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send data over a network.
|
* Send data over a network.
|
||||||
* @param sock The socket to send the data over.
|
* @param sock The socket to send the data over.
|
||||||
|
@ -814,7 +814,6 @@ SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, s
|
|||||||
new_sa = apr_pcalloc(pool, sizeof(apr_sockaddr_t));
|
new_sa = apr_pcalloc(pool, sizeof(apr_sockaddr_t));
|
||||||
switch_assert(new_sa);
|
switch_assert(new_sa);
|
||||||
new_sa->pool = pool;
|
new_sa->pool = pool;
|
||||||
memset(new_sa, 0, sizeof(*new_sa));
|
|
||||||
|
|
||||||
new_sa->family = family;
|
new_sa->family = family;
|
||||||
new_sa->sa.sin.sin_family = family;
|
new_sa->sa.sin.sin_family = family;
|
||||||
@ -834,6 +833,65 @@ SWITCH_DECLARE(switch_status_t) switch_sockaddr_info_get(switch_sockaddr_t ** sa
|
|||||||
return apr_sockaddr_info_get(sa, hostname, family, port, flags, pool);
|
return apr_sockaddr_info_get(sa, hostname, family, port, flags, pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_sockaddr_new(switch_sockaddr_t ** sa, const char *ip, switch_port_t port, switch_memory_pool_t *pool)
|
||||||
|
{
|
||||||
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||||
|
apr_sockaddr_t *new_sa;
|
||||||
|
int family;
|
||||||
|
|
||||||
|
if (!sa || !pool || !ip) {
|
||||||
|
switch_goto_status(SWITCH_STATUS_GENERR, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
new_sa = apr_pcalloc(pool, sizeof(apr_sockaddr_t));
|
||||||
|
switch_assert(new_sa);
|
||||||
|
|
||||||
|
new_sa->pool = pool;
|
||||||
|
|
||||||
|
if (strchr(ip, ':')) {
|
||||||
|
struct sockaddr_in6 sa6 = { 0 };
|
||||||
|
|
||||||
|
family = APR_INET6;
|
||||||
|
inet_pton(family, ip, &(sa6.sin6_addr));
|
||||||
|
memcpy(&new_sa->sa, &sa6, sizeof(struct sockaddr_in6));
|
||||||
|
} else {
|
||||||
|
struct sockaddr_in sa4 = { 0 };
|
||||||
|
|
||||||
|
family = APR_INET;
|
||||||
|
inet_pton(family, ip, &(sa4.sin_addr));
|
||||||
|
memcpy(&new_sa->sa, &sa4, sizeof(struct sockaddr_in));
|
||||||
|
}
|
||||||
|
|
||||||
|
new_sa->hostname = apr_pstrdup(pool, ip);
|
||||||
|
new_sa->family = family;
|
||||||
|
new_sa->sa.sin.sin_family = family;
|
||||||
|
if (port) {
|
||||||
|
/* XXX IPv6: assumes sin_port and sin6_port at same offset */
|
||||||
|
new_sa->sa.sin.sin_port = htons(port);
|
||||||
|
new_sa->port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (family == APR_INET) {
|
||||||
|
new_sa->salen = sizeof(struct sockaddr_in);
|
||||||
|
new_sa->addr_str_len = 16;
|
||||||
|
new_sa->ipaddr_ptr = &(new_sa->sa.sin.sin_addr);
|
||||||
|
new_sa->ipaddr_len = sizeof(struct in_addr);
|
||||||
|
}
|
||||||
|
#if APR_HAVE_IPV6
|
||||||
|
else if (family == APR_INET6) {
|
||||||
|
new_sa->salen = sizeof(struct sockaddr_in6);
|
||||||
|
new_sa->addr_str_len = 46;
|
||||||
|
new_sa->ipaddr_ptr = &(new_sa->sa.sin6.sin6_addr);
|
||||||
|
new_sa->ipaddr_len = sizeof(struct in6_addr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*sa = new_sa;
|
||||||
|
|
||||||
|
end:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_socket_opt_set(switch_socket_t *sock, int32_t opt, int32_t on)
|
SWITCH_DECLARE(switch_status_t) switch_socket_opt_set(switch_socket_t *sock, int32_t opt, int32_t on)
|
||||||
{
|
{
|
||||||
if (opt == SWITCH_SO_TCP_KEEPIDLE) {
|
if (opt == SWITCH_SO_TCP_KEEPIDLE) {
|
||||||
|
@ -115,7 +115,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_new(const char *ip, s
|
|||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_bool_t test_port(switch_core_port_allocator_t *alloc, int family, int type, switch_port_t port)
|
static switch_bool_t test_port(switch_core_port_allocator_t *alloc, int type, switch_port_t port)
|
||||||
{
|
{
|
||||||
switch_memory_pool_t *pool = NULL;
|
switch_memory_pool_t *pool = NULL;
|
||||||
switch_sockaddr_t *local_addr = NULL;
|
switch_sockaddr_t *local_addr = NULL;
|
||||||
@ -126,8 +126,8 @@ static switch_bool_t test_port(switch_core_port_allocator_t *alloc, int family,
|
|||||||
return SWITCH_FALSE;
|
return SWITCH_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switch_sockaddr_info_get(&local_addr, alloc->ip, SWITCH_UNSPEC, port, 0, pool) == SWITCH_STATUS_SUCCESS) {
|
if (switch_sockaddr_new(&local_addr, alloc->ip, port, pool) == SWITCH_STATUS_SUCCESS) {
|
||||||
if (switch_socket_create(&sock, family, type, 0, pool) == SWITCH_STATUS_SUCCESS) {
|
if (switch_socket_create(&sock, switch_sockaddr_get_family(local_addr), type, 0, pool) == SWITCH_STATUS_SUCCESS) {
|
||||||
if (switch_socket_bind(sock, local_addr) == SWITCH_STATUS_SUCCESS) {
|
if (switch_socket_bind(sock, local_addr) == SWITCH_STATUS_SUCCESS) {
|
||||||
r = SWITCH_TRUE;
|
r = SWITCH_TRUE;
|
||||||
}
|
}
|
||||||
@ -179,12 +179,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_request_port(switch_c
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((alloc->flags & SPF_ROBUST_UDP)) {
|
if ((alloc->flags & SPF_ROBUST_UDP)) {
|
||||||
r = test_port(alloc, AF_INET, SOCK_DGRAM, port);
|
r = test_port(alloc, SOCK_DGRAM, port);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "UDP port robustness check for port %d %s\n", port, r ? "pass" : "fail");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "UDP port robustness check for port %d %s\n", port, r ? "pass" : "fail");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((alloc->flags & SPF_ROBUST_TCP)) {
|
if ((alloc->flags & SPF_ROBUST_TCP)) {
|
||||||
r = test_port(alloc, AF_INET, SOCK_STREAM, port);
|
r = test_port(alloc, SOCK_STREAM, port);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TCP port robustness check for port %d %s\n", port, r ? "pass" : "fail");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TCP port robustness check for port %d %s\n", port, r ? "pass" : "fail");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +82,34 @@ FST_CORE_BEGIN("./conf")
|
|||||||
switch_safe_free(var_default_password);
|
switch_safe_free(var_default_password);
|
||||||
}
|
}
|
||||||
FST_TEST_END()
|
FST_TEST_END()
|
||||||
|
|
||||||
|
FST_TEST_BEGIN(test_switch_sockaddr_new)
|
||||||
|
{
|
||||||
|
int type = SOCK_DGRAM;
|
||||||
|
switch_port_t port = 12044;
|
||||||
|
const char *ip = "127.0.0.1";
|
||||||
|
|
||||||
|
switch_memory_pool_t *pool = NULL;
|
||||||
|
switch_sockaddr_t *local_addr = NULL;
|
||||||
|
switch_socket_t *sock = NULL;
|
||||||
|
switch_bool_t r = SWITCH_FALSE;
|
||||||
|
|
||||||
|
if (switch_core_new_memory_pool(&pool) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
if (switch_sockaddr_new(&local_addr, ip, port, pool) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
if (switch_socket_create(&sock, switch_sockaddr_get_family(local_addr), type, 0, pool) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
if (switch_socket_bind(sock, local_addr) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
r = SWITCH_TRUE;
|
||||||
|
}
|
||||||
|
switch_socket_close(sock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_core_destroy_memory_pool(&pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
fst_check_int_equals(r, SWITCH_TRUE);
|
||||||
|
}
|
||||||
|
FST_TEST_END()
|
||||||
}
|
}
|
||||||
FST_SUITE_END()
|
FST_SUITE_END()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user