From 34878d7b05813e090b370f48b8d437e4bd875094 Mon Sep 17 00:00:00 2001 From: Vita Batrla Date: Fri, 17 Jan 2020 14:43:36 +0100 Subject: [PATCH 1/4] Options IP_MULTICAST_TTL and IP_MULTICAST_LOOP are 1 byte on BSD and Solaris See ip(4P) man page: IP_MULTICAST_TTL Time to live for multicast datagrams. This option takes an unsigned character as an argument. Its value is the TTL that IP uses on outgoing multi- cast datagrams. The default is 1. IP_MULTICAST_LOOP Loopback for multicast datagrams. Normally multi- cast datagrams are delivered to members on the sending host (or sending zone). Setting the unsigned character argument to 0 causes the oppo- site behavior, meaning that when multiple zones are present, the datagrams are delivered to all zones except the sending zone. https://docs.oracle.com/cd/E88353_01/html/E37851/ip-4p.html https://man.openbsd.org/ip.4 --- src/libstd/sys_common/net.rs | 68 ++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index c7d4828892c04..32e392f1efc86 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -12,6 +12,10 @@ use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::time::Duration; use libc::{c_int, c_void}; +#[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "openbsd", target_os = "netbsd", + target_os = "solaris"))] +use libc::{c_uchar}; #[cfg(not(any( target_os = "dragonfly", @@ -565,24 +569,6 @@ impl UdpSocket { Ok(raw != 0) } - pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as c_int) - } - - pub fn multicast_loop_v4(&self) -> io::Result { - let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; - Ok(raw != 0) - } - - pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as c_int) - } - - pub fn multicast_ttl_v4(&self) -> io::Result { - let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; - Ok(raw as u32) - } - pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> { setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP, multicast_loop_v6 as c_int) } @@ -663,6 +649,52 @@ impl UdpSocket { } } +#[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "openbsd", target_os = "netbsd", + target_os = "solaris")))] +impl UdpSocket { + pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { + setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as c_int) + } + + pub fn multicast_loop_v4(&self) -> io::Result { + let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; + Ok(raw != 0) + } + + pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { + setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as c_int) + } + + pub fn multicast_ttl_v4(&self) -> io::Result { + let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; + Ok(raw as u32) + } +} + +#[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "openbsd", target_os = "netbsd", + target_os = "solaris"))] +impl UdpSocket { + pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { + setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as c_uchar) + } + + pub fn multicast_loop_v4(&self) -> io::Result { + let raw: c_uchar = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; + Ok(raw != 0) + } + + pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { + setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as c_uchar) + } + + pub fn multicast_ttl_v4(&self) -> io::Result { + let raw: c_uchar = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; + Ok(raw as u32) + } +} + impl FromInner for UdpSocket { fn from_inner(socket: Socket) -> UdpSocket { UdpSocket { inner: socket } From dda32e4e535fb3fb9e728b8c96386db7d231b247 Mon Sep 17 00:00:00 2001 From: Vita Batrla Date: Fri, 17 Jan 2020 22:46:32 +0100 Subject: [PATCH 2/4] refactor fix using cfg_if! --- src/libstd/sys_common/net.rs | 175 +++++++++++------------------------ 1 file changed, 55 insertions(+), 120 deletions(-) diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index 32e392f1efc86..152da978bfd85 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -12,80 +12,43 @@ use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::time::Duration; use libc::{c_int, c_void}; -#[cfg(any(target_os = "dragonfly", target_os = "freebsd", - target_os = "openbsd", target_os = "netbsd", - target_os = "solaris"))] -use libc::{c_uchar}; - -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "netbsd", - target_os = "solaris", - target_os = "haiku", - target_os = "l4re" -)))] -use crate::sys::net::netc::IPV6_ADD_MEMBERSHIP; -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "netbsd", - target_os = "solaris", - target_os = "haiku", - target_os = "l4re" -)))] -use crate::sys::net::netc::IPV6_DROP_MEMBERSHIP; -#[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "netbsd", - target_os = "solaris", - target_os = "haiku", - target_os = "l4re" -))] -use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; -#[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "netbsd", - target_os = "solaris", - target_os = "haiku", - target_os = "l4re" -))] -use crate::sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; - -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "openbsd", - target_os = "netbsd", - target_os = "haiku" -))] -use libc::MSG_NOSIGNAL; -#[cfg(not(any( - target_os = "linux", - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "openbsd", - target_os = "netbsd", - target_os = "haiku" -)))] -const MSG_NOSIGNAL: c_int = 0x0; + +cfg_if::cfg_if! { + if #[cfg(any( + target_os = "dragonfly", target_os = "freebsd", + target_os = "ios", target_os = "macos", + target_os = "openbsd", target_os = "netbsd", + target_os = "solaris", target_os = "haiku", target_os = "l4re"))] { + use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; + use crate::sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; + } else { + use crate::sys::net::netc::IPV6_ADD_MEMBERSHIP; + use crate::sys::net::netc::IPV6_DROP_MEMBERSHIP; + } +} + +cfg_if::cfg_if! { + if #[cfg(any( + target_os = "linux", target_os = "android", + target_os = "dragonfly", target_os = "freebsd", + target_os = "openbsd", target_os = "netbsd", + target_os = "haiku"))] { + use libc::MSG_NOSIGNAL; + } else { + const MSG_NOSIGNAL: c_int = 0x0; + } +} + +cfg_if::cfg_if! { + if #[cfg(any( + target_os = "dragonfly", target_os = "freebsd", + target_os = "openbsd", target_os = "netbsd", + target_os = "solaris"))] { + type ip_mcast_type_v4 = c_uchar; + } else { + type ip_mcast_type_v4 = c_int; + } +} //////////////////////////////////////////////////////////////////////////////// // sockaddr and misc bindings @@ -569,6 +532,24 @@ impl UdpSocket { Ok(raw != 0) } + pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { + setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as ip_mcast_type_v4) + } + + pub fn multicast_loop_v4(&self) -> io::Result { + let raw: ip_mcast_type_v4 = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; + Ok(raw != 0) + } + + pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { + setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as ip_mcast_type_v4) + } + + pub fn multicast_ttl_v4(&self) -> io::Result { + let raw: ip_mcast_type_v4 = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; + Ok(raw as u32) + } + pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> { setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP, multicast_loop_v6 as c_int) } @@ -649,52 +630,6 @@ impl UdpSocket { } } -#[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", - target_os = "openbsd", target_os = "netbsd", - target_os = "solaris")))] -impl UdpSocket { - pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as c_int) - } - - pub fn multicast_loop_v4(&self) -> io::Result { - let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; - Ok(raw != 0) - } - - pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as c_int) - } - - pub fn multicast_ttl_v4(&self) -> io::Result { - let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; - Ok(raw as u32) - } -} - -#[cfg(any(target_os = "dragonfly", target_os = "freebsd", - target_os = "openbsd", target_os = "netbsd", - target_os = "solaris"))] -impl UdpSocket { - pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as c_uchar) - } - - pub fn multicast_loop_v4(&self) -> io::Result { - let raw: c_uchar = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; - Ok(raw != 0) - } - - pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as c_uchar) - } - - pub fn multicast_ttl_v4(&self) -> io::Result { - let raw: c_uchar = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; - Ok(raw as u32) - } -} - impl FromInner for UdpSocket { fn from_inner(socket: Socket) -> UdpSocket { UdpSocket { inner: socket } From 239a7d9124ee486e9d0096429136d719437b83b2 Mon Sep 17 00:00:00 2001 From: Vita Batrla Date: Sat, 18 Jan 2020 00:38:37 +0100 Subject: [PATCH 3/4] refactor fix using cfg_if! (fix build) --- src/libstd/sys_common/net.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index 152da978bfd85..7e603a8682ba5 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -44,9 +44,9 @@ cfg_if::cfg_if! { target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "solaris"))] { - type ip_mcast_type_v4 = c_uchar; + type IpV4MultiCastType = c_uchar; } else { - type ip_mcast_type_v4 = c_int; + type IpV4MultiCastType = c_int; } } @@ -533,20 +533,30 @@ impl UdpSocket { } pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as ip_mcast_type_v4) + setsockopt( + &self.inner, + c::IPPROTO_IP, + c::IP_MULTICAST_LOOP, + multicast_loop_v4 as IpV4MultiCastType, + ) } pub fn multicast_loop_v4(&self) -> io::Result { - let raw: ip_mcast_type_v4 = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; + let raw: IpV4MultiCastType = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?; Ok(raw != 0) } pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { - setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as ip_mcast_type_v4) + setsockopt( + &self.inner, + c::IPPROTO_IP, + c::IP_MULTICAST_TTL, + multicast_ttl_v4 as IpV4MultiCastType, + ) } pub fn multicast_ttl_v4(&self) -> io::Result { - let raw: ip_mcast_type_v4 = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; + let raw: IpV4MultiCastType = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?; Ok(raw as u32) } From 53924428692371a175afeaaa5fa410c44f0e06ae Mon Sep 17 00:00:00 2001 From: Vita Batrla Date: Mon, 20 Jan 2020 19:15:37 +0100 Subject: [PATCH 4/4] refactor fix using cfg_if! (fix build on Solaris) --- src/libstd/sys_common/net.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index 7e603a8682ba5..135e8308afaea 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -44,6 +44,7 @@ cfg_if::cfg_if! { target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "solaris"))] { + use libc::c_uchar; type IpV4MultiCastType = c_uchar; } else { type IpV4MultiCastType = c_int;