Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
uv: fix setsockopt for multicast options
Browse files Browse the repository at this point in the history
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: libuv/libuv#243

Reviewed-By: Julien Gilli <julien.gilli@joyent.com>
PR-URL: #9179
  • Loading branch information
Julien Gilli authored and trevnorris committed Mar 19, 2015
1 parent 3cce8ab commit 9613ac7
Showing 1 changed file with 69 additions and 18 deletions.
87 changes: 69 additions & 18 deletions deps/uv/src/unix/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down

0 comments on commit 9613ac7

Please sign in to comment.