1
0
mirror of https://github.com/libuv/libuv synced 2025-03-28 21:13:16 +00:00

unix: fix ttl, multicast ttl and loop options on IPv6

Fixes #93

PR-URL: https://github.com/libuv/libuv/pull/99
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
Saúl Ibarra Corretgé 2015-01-01 13:15:57 +01:00
parent a31024865b
commit 2daee9fbeb
3 changed files with 51 additions and 13 deletions

View File

@ -598,7 +598,11 @@ int uv_udp_set_membership(uv_udp_t* handle,
}
static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) {
static int uv__setsockopt_maybe_char(uv_udp_t* handle,
int option4,
int option6,
int val) {
int r;
#if defined(__sun) || defined(_AIX)
char arg = val;
#else
@ -608,7 +612,20 @@ static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) {
if (val < 0 || val > 255)
return -EINVAL;
if (setsockopt(handle->io_watcher.fd, IPPROTO_IP, option, &arg, sizeof(arg)))
if (handle->flags & UV_HANDLE_IPV6)
r = setsockopt(handle->io_watcher.fd,
IPPROTO_IPV6,
option6,
&arg,
sizeof(arg));
else
r = setsockopt(handle->io_watcher.fd,
IPPROTO_IP,
option4,
&arg,
sizeof(arg));
if (r)
return -errno;
return 0;
@ -632,20 +649,26 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
if (ttl < 1 || ttl > 255)
return -EINVAL;
if (setsockopt(handle->io_watcher.fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)))
return -errno;
return 0;
return uv__setsockopt_maybe_char(handle,
IP_TTL,
IPV6_UNICAST_HOPS,
ttl);
}
int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
return uv__setsockopt_maybe_char(handle, IP_MULTICAST_TTL, ttl);
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_TTL,
IPV6_MULTICAST_HOPS,
ttl);
}
int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
return uv__setsockopt_maybe_char(handle, IP_MULTICAST_LOOP, on);
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_LOOP,
IPV6_MULTICAST_LOOP,
on);
}
int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {

View File

@ -104,6 +104,7 @@ TEST_DECLARE (udp_dgram_too_big)
TEST_DECLARE (udp_dual_stack)
TEST_DECLARE (udp_ipv6_only)
TEST_DECLARE (udp_options)
TEST_DECLARE (udp_options6)
TEST_DECLARE (udp_no_autobind)
TEST_DECLARE (udp_open)
TEST_DECLARE (udp_try_send)
@ -413,6 +414,7 @@ TASK_LIST_START
TEST_ENTRY (udp_dual_stack)
TEST_ENTRY (udp_ipv6_only)
TEST_ENTRY (udp_options)
TEST_ENTRY (udp_options6)
TEST_ENTRY (udp_no_autobind)
TEST_ENTRY (udp_multicast_interface)
TEST_ENTRY (udp_multicast_interface6)

View File

@ -27,15 +27,12 @@
#include <string.h>
TEST_IMPL(udp_options) {
static int udp_options_test(const struct sockaddr* addr) {
static int invalid_ttls[] = { -1, 0, 256 };
struct sockaddr_in addr;
uv_loop_t* loop;
uv_udp_t h;
int i, r;
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
loop = uv_default_loop();
r = uv_udp_init(loop, &h);
@ -43,7 +40,7 @@ TEST_IMPL(udp_options) {
uv_unref((uv_handle_t*)&h); /* don't keep the loop alive */
r = uv_udp_bind(&h, (const struct sockaddr*) &addr, 0);
r = uv_udp_bind(&h, addr, 0);
ASSERT(r == 0);
r = uv_udp_set_broadcast(&h, 1);
@ -88,6 +85,22 @@ TEST_IMPL(udp_options) {
}
TEST_IMPL(udp_options) {
struct sockaddr_in addr;
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
return udp_options_test((const struct sockaddr*) &addr);
}
TEST_IMPL(udp_options6) {
struct sockaddr_in6 addr;
ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr));
return udp_options_test((const struct sockaddr*) &addr);
}
TEST_IMPL(udp_no_autobind) {
uv_loop_t* loop;
uv_udp_t h;