summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Gilli <julien.gilli@joyent.com>2015-03-04 17:27:49 -0800
committerJulien Gilli <julien.gilli@joyent.com>2015-03-10 16:19:16 -0700
commited644e727db1557e24f09ef511a539c710a38bf2 (patch)
treec037cff88b3bf4d0fa986216840a197435e2827f
parentd6d89e353b219f6bddb5379051779a6a2121119b (diff)
downloadnode-libuv-upgrade-latest-1x.tar.gz
solaris: fix setsockopt for multicast optionslibuv-upgrade-latest-1x
On Solaris and derivatives such as SmartOS, the length of socket options for multicast and ttl options is not always sizeof(char). This fixes the udp_options and udp_options6 tests.
-rw-r--r--deps/uv/src/unix/udp.c87
1 files changed, 69 insertions, 18 deletions
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index 8c78884c0..89903de0e 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -601,40 +601,47 @@ int uv_udp_set_membership(uv_udp_t* handle,
}
}
-
-static int uv__setsockopt_maybe_char(uv_udp_t* handle,
- int option4,
- int option6,
- int val) {
+static int uv__setsockopt(uv_udp_t* handle,
+ int option4,
+ int option6,
+ const void* val,
+ size_t size) {
int r;
-#if defined(__sun) || defined(_AIX)
- char arg = val;
-#else
- int arg = val;
-#endif
-
- if (val < 0 || val > 255)
- return -EINVAL;
if (handle->flags & UV_HANDLE_IPV6)
r = setsockopt(handle->io_watcher.fd,
IPPROTO_IPV6,
option6,
- &arg,
- sizeof(arg));
+ val,
+ size);
else
r = setsockopt(handle->io_watcher.fd,
IPPROTO_IP,
option4,
- &arg,
- sizeof(arg));
-
+ val,
+ size);
if (r)
return -errno;
return 0;
}
+static int uv__setsockopt_maybe_char(uv_udp_t* handle,
+ int option4,
+ int option6,
+ int val) {
+#if defined(__sun) || defined(_AIX)
+ char arg = val;
+#else
+ int arg = val;
+#endif
+
+ if (val < 0 || val > 255)
+ return -EINVAL;
+
+ return uv__setsockopt(handle, option4, option6, &arg, sizeof(arg));
+}
+
int uv_udp_set_broadcast(uv_udp_t* handle, int on) {
if (setsockopt(handle->io_watcher.fd,
@@ -653,6 +660,20 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
if (ttl < 1 || ttl > 255)
return -EINVAL;
+/*
+ * On Solaris and derivatives such as SmartOS, the length of socket options
+ * is sizeof(int) for IP_TTL and IPV6_UNICAST_HOPS,
+ * so hardcode the size of these options on this platform,
+ * and use the general uv__setsockopt_maybe_char call on other platforms.
+ */
+#if defined(__sun)
+ return uv__setsockopt(handle,
+ IP_TTL,
+ IPV6_UNICAST_HOPS,
+ &ttl,
+ sizeof(ttl));
+#endif /* defined(__sun) */
+
return uv__setsockopt_maybe_char(handle,
IP_TTL,
IPV6_UNICAST_HOPS,
@@ -661,6 +682,21 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
+/*
+ * On Solaris and derivatives such as SmartOS, the length of socket options
+ * is sizeof(int) for IPV6_MULTICAST_HOPS and sizeof(char) for
+ * IP_MULTICAST_TTL, so hardcode the size of the option in the IPv6 case,
+ * and use the general uv__setsockopt_maybe_char call otherwise.
+ */
+#if defined(__sun)
+ if (handle->flags & UV_HANDLE_IPV6)
+ return uv__setsockopt(handle,
+ IP_MULTICAST_TTL,
+ IPV6_MULTICAST_HOPS,
+ &ttl,
+ sizeof(ttl));
+#endif /* defined(__sun) */
+
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_TTL,
IPV6_MULTICAST_HOPS,
@@ -669,6 +705,21 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
+/*
+ * On Solaris and derivatives such as SmartOS, the length of socket options
+ * is sizeof(int) for IPV6_MULTICAST_LOOP and sizeof(char) for
+ * IP_MULTICAST_LOOP, so hardcode the size of the option in the IPv6 case,
+ * and use the general uv__setsockopt_maybe_char call otherwise.
+ */
+#if defined(__sun)
+ if (handle->flags & UV_HANDLE_IPV6)
+ return uv__setsockopt(handle,
+ IP_MULTICAST_LOOP,
+ IPV6_MULTICAST_LOOP,
+ &on,
+ sizeof(on));
+#endif /* defined(__sun) */
+
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_LOOP,
IPV6_MULTICAST_LOOP,