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.
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;
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) {
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;
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;
}
}
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");
}
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()
}