[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_new(switch_sockaddr_t ** sa, const char *ip, switch_port_t port, switch_memory_pool_t *pool);
|
||||
|
||||
/**
|
||||
* Send data over a network.
|
||||
* @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));
|
||||
switch_assert(new_sa);
|
||||
new_sa->pool = pool;
|
||||
memset(new_sa, 0, sizeof(*new_sa));
|
||||
|
||||
new_sa->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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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_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;
|
||||
}
|
||||
|
||||
if (switch_sockaddr_info_get(&local_addr, alloc->ip, SWITCH_UNSPEC, port, 0, pool) == SWITCH_STATUS_SUCCESS) {
|
||||
if (switch_socket_create(&sock, family, type, 0, pool) == SWITCH_STATUS_SUCCESS) {
|
||||
if (switch_sockaddr_new(&local_addr, alloc->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;
|
||||
}
|
||||
|
@ -179,12 +179,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_request_port(switch_c
|
|||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,34 @@ FST_CORE_BEGIN("./conf")
|
|||
switch_safe_free(var_default_password);
|
||||
}
|
||||
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()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue