Browse Source

uv: fix setsockopt for multicast options

Float patch to fix setsockopt for multicast on Solaris and derivatives.
Original commit message:

  solaris: fix setsockopt for multicast options

  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.

Ref: https://github.com/libuv/libuv/pull/243

Reviewed-By: Julien Gilli <julien.gilli@joyent.com>
PR-URL: https://github.com/joyent/node/pull/9179
v0.12.2-release
Julien Gilli 10 years ago
committed by Trevor Norris
parent
commit
9613ac7cb8
  1. 83
      deps/uv/src/unix/udp.c

83
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,
static int uv__setsockopt(uv_udp_t* handle,
int option4,
int option6,
int val) {
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,

Loading…
Cancel
Save