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

Commit 9613ac7

Browse files
Julien Gillitrevnorris
authored andcommitted
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: libuv/libuv#243 Reviewed-By: Julien Gilli <julien.gilli@joyent.com> PR-URL: #9179
1 parent 3cce8ab commit 9613ac7

File tree

1 file changed

+69
-18
lines changed

1 file changed

+69
-18
lines changed

deps/uv/src/unix/udp.c

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -601,40 +601,47 @@ int uv_udp_set_membership(uv_udp_t* handle,
601601
}
602602
}
603603

604-
605-
static int uv__setsockopt_maybe_char(uv_udp_t* handle,
606-
int option4,
607-
int option6,
608-
int val) {
604+
static int uv__setsockopt(uv_udp_t* handle,
605+
int option4,
606+
int option6,
607+
const void* val,
608+
size_t size) {
609609
int r;
610-
#if defined(__sun) || defined(_AIX)
611-
char arg = val;
612-
#else
613-
int arg = val;
614-
#endif
615-
616-
if (val < 0 || val > 255)
617-
return -EINVAL;
618610

619611
if (handle->flags & UV_HANDLE_IPV6)
620612
r = setsockopt(handle->io_watcher.fd,
621613
IPPROTO_IPV6,
622614
option6,
623-
&arg,
624-
sizeof(arg));
615+
val,
616+
size);
625617
else
626618
r = setsockopt(handle->io_watcher.fd,
627619
IPPROTO_IP,
628620
option4,
629-
&arg,
630-
sizeof(arg));
631-
621+
val,
622+
size);
632623
if (r)
633624
return -errno;
634625

635626
return 0;
636627
}
637628

629+
static int uv__setsockopt_maybe_char(uv_udp_t* handle,
630+
int option4,
631+
int option6,
632+
int val) {
633+
#if defined(__sun) || defined(_AIX)
634+
char arg = val;
635+
#else
636+
int arg = val;
637+
#endif
638+
639+
if (val < 0 || val > 255)
640+
return -EINVAL;
641+
642+
return uv__setsockopt(handle, option4, option6, &arg, sizeof(arg));
643+
}
644+
638645

639646
int uv_udp_set_broadcast(uv_udp_t* handle, int on) {
640647
if (setsockopt(handle->io_watcher.fd,
@@ -653,6 +660,20 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
653660
if (ttl < 1 || ttl > 255)
654661
return -EINVAL;
655662

663+
/*
664+
* On Solaris and derivatives such as SmartOS, the length of socket options
665+
* is sizeof(int) for IP_TTL and IPV6_UNICAST_HOPS,
666+
* so hardcode the size of these options on this platform,
667+
* and use the general uv__setsockopt_maybe_char call on other platforms.
668+
*/
669+
#if defined(__sun)
670+
return uv__setsockopt(handle,
671+
IP_TTL,
672+
IPV6_UNICAST_HOPS,
673+
&ttl,
674+
sizeof(ttl));
675+
#endif /* defined(__sun) */
676+
656677
return uv__setsockopt_maybe_char(handle,
657678
IP_TTL,
658679
IPV6_UNICAST_HOPS,
@@ -661,6 +682,21 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
661682

662683

663684
int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
685+
/*
686+
* On Solaris and derivatives such as SmartOS, the length of socket options
687+
* is sizeof(int) for IPV6_MULTICAST_HOPS and sizeof(char) for
688+
* IP_MULTICAST_TTL, so hardcode the size of the option in the IPv6 case,
689+
* and use the general uv__setsockopt_maybe_char call otherwise.
690+
*/
691+
#if defined(__sun)
692+
if (handle->flags & UV_HANDLE_IPV6)
693+
return uv__setsockopt(handle,
694+
IP_MULTICAST_TTL,
695+
IPV6_MULTICAST_HOPS,
696+
&ttl,
697+
sizeof(ttl));
698+
#endif /* defined(__sun) */
699+
664700
return uv__setsockopt_maybe_char(handle,
665701
IP_MULTICAST_TTL,
666702
IPV6_MULTICAST_HOPS,
@@ -669,6 +705,21 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
669705

670706

671707
int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
708+
/*
709+
* On Solaris and derivatives such as SmartOS, the length of socket options
710+
* is sizeof(int) for IPV6_MULTICAST_LOOP and sizeof(char) for
711+
* IP_MULTICAST_LOOP, so hardcode the size of the option in the IPv6 case,
712+
* and use the general uv__setsockopt_maybe_char call otherwise.
713+
*/
714+
#if defined(__sun)
715+
if (handle->flags & UV_HANDLE_IPV6)
716+
return uv__setsockopt(handle,
717+
IP_MULTICAST_LOOP,
718+
IPV6_MULTICAST_LOOP,
719+
&on,
720+
sizeof(on));
721+
#endif /* defined(__sun) */
722+
672723
return uv__setsockopt_maybe_char(handle,
673724
IP_MULTICAST_LOOP,
674725
IPV6_MULTICAST_LOOP,

0 commit comments

Comments
 (0)