From f5fc36db29155e395667cc3fd1a27ff4140bd332 Mon Sep 17 00:00:00 2001 From: cavivie Date: Fri, 2 Aug 2024 18:39:21 +0800 Subject: [PATCH 1/6] Move (set_)ip_transparent to sys unix module --- src/socket.rs | 42 ------------------------------------------ src/sys/unix.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/socket.rs b/src/socket.rs index 8d517b47..70f339bb 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1212,48 +1212,6 @@ impl Socket { } } - /// Get the value of the `IP_TRANSPARENT` option on this socket. - /// - /// For more information about this option, see [`set_ip_transparent`]. - /// - /// [`set_ip_transparent`]: Socket::set_ip_transparent - #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] - pub fn ip_transparent(&self) -> io::Result { - unsafe { - getsockopt::(self.as_raw(), sys::IPPROTO_IP, libc::IP_TRANSPARENT) - .map(|transparent| transparent != 0) - } - } - - /// Set the value of the `IP_TRANSPARENT` option on this socket. - /// - /// Setting this boolean option enables transparent proxying - /// on this socket. This socket option allows the calling - /// application to bind to a nonlocal IP address and operate - /// both as a client and a server with the foreign address as - /// the local endpoint. NOTE: this requires that routing be - /// set up in a way that packets going to the foreign address - /// are routed through the TProxy box (i.e., the system - /// hosting the application that employs the IP_TRANSPARENT - /// socket option). Enabling this socket option requires - /// superuser privileges (the `CAP_NET_ADMIN` capability). - /// - /// TProxy redirection with the iptables TPROXY target also - /// requires that this option be set on the redirected socket. - #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] - pub fn set_ip_transparent(&self, transparent: bool) -> io::Result<()> { - unsafe { - setsockopt( - self.as_raw(), - sys::IPPROTO_IP, - libc::IP_TRANSPARENT, - transparent as c_int, - ) - } - } - /// Join a multicast group using `IP_ADD_MEMBERSHIP` option on this socket. /// /// This function specifies a new multicast group for this socket to join. diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 3a898bc3..7c3f92d3 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -3097,6 +3097,48 @@ impl crate::Socket { ) } } + + /// Get the value of the `IP_TRANSPARENT` option on this socket. + /// + /// For more information about this option, see [`set_ip_transparent`]. + /// + /// [`set_ip_transparent`]: Socket::set_ip_transparent + #[cfg(all(feature = "all", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] + pub fn ip_transparent(&self) -> io::Result { + unsafe { + getsockopt::(self.as_raw(), libc::IPPROTO_IP, libc::IP_TRANSPARENT) + .map(|transparent| transparent != 0) + } + } + + /// Set the value of the `IP_TRANSPARENT` option on this socket. + /// + /// Setting this boolean option enables transparent proxying + /// on this socket. This socket option allows the calling + /// application to bind to a nonlocal IP address and operate + /// both as a client and a server with the foreign address as + /// the local endpoint. NOTE: this requires that routing be + /// set up in a way that packets going to the foreign address + /// are routed through the TProxy box (i.e., the system + /// hosting the application that employs the IP_TRANSPARENT + /// socket option). Enabling this socket option requires + /// superuser privileges (the `CAP_NET_ADMIN` capability). + /// + /// TProxy redirection with the iptables TPROXY target also + /// requires that this option be set on the redirected socket. + #[cfg(all(feature = "all", target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] + pub fn set_ip_transparent(&self, transparent: bool) -> io::Result<()> { + unsafe { + setsockopt( + self.as_raw(), + libc::IPPROTO_IP, + libc::IP_TRANSPARENT, + transparent as c_int, + ) + } + } } /// See [`Socket::dccp_available_ccids`]. From 7cbd05c6751c19035325ead72cc7e1fd265475b0 Mon Sep 17 00:00:00 2001 From: cavivie Date: Fri, 2 Aug 2024 18:42:38 +0800 Subject: [PATCH 2/6] Add target_os=android/fuchisa for (set_)ip_transparent --- src/sys/unix.rs | 26 ++++++++++++++++++++++---- tests/socket.rs | 5 ++++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 7c3f92d3..f51f05d0 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -3103,8 +3103,17 @@ impl crate::Socket { /// For more information about this option, see [`set_ip_transparent`]. /// /// [`set_ip_transparent`]: Socket::set_ip_transparent - #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] + #[cfg(all( + feature = "all", + any(target_os = "android", target_os = "linux", target_os = "fuchsia") + ))] + #[cfg_attr( + docsrs, + doc(cfg(all( + feature = "all", + any(target_os = "android", target_os = "linux", target_os = "fuchsia") + ))) + )] pub fn ip_transparent(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::IPPROTO_IP, libc::IP_TRANSPARENT) @@ -3127,8 +3136,17 @@ impl crate::Socket { /// /// TProxy redirection with the iptables TPROXY target also /// requires that this option be set on the redirected socket. - #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] + #[cfg(all( + feature = "all", + any(target_os = "android", target_os = "linux", target_os = "fuchsia") + ))] + #[cfg_attr( + docsrs, + doc(cfg(all( + feature = "all", + any(target_os = "android", target_os = "linux", target_os = "fuchsia") + ))) + )] pub fn set_ip_transparent(&self, transparent: bool) -> io::Result<()> { unsafe { setsockopt( diff --git a/tests/socket.rs b/tests/socket.rs index 2300f0ed..fa17376d 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1363,7 +1363,10 @@ test!( mss, set_mss(256) ); -#[cfg(all(feature = "all", target_os = "linux"))] +#[cfg(all( + feature = "all", + any(target_os = "android", target_os = "linux", target_os = "fuchsia") +))] test!( #[ignore = "setting `IP_TRANSPARENT` requires the `CAP_NET_ADMIN` capability (works when running as root)"] ip_transparent, From 4b89bf827501eb7b0a3605fca77b974e33b2546e Mon Sep 17 00:00:00 2001 From: cavivie Date: Fri, 2 Aug 2024 18:50:46 +0800 Subject: [PATCH 3/6] Deprecate (set_)ip_transparent in favour of (set_)ip_transparent_v4 --- src/sys/unix.rs | 42 ++++++++++++++++++++++++++++++++++++++---- tests/socket.rs | 4 ++-- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/sys/unix.rs b/src/sys/unix.rs index f51f05d0..7c684e9a 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -3098,11 +3098,28 @@ impl crate::Socket { } } + /// This method is deprecated, use [`crate::Socket::ip_transparent_v4`]. + #[cfg(all( + feature = "all", + any(target_os = "android", target_os = "linux", target_os = "fuchsia") + ))] + #[cfg_attr( + docsrs, + doc(cfg(all( + feature = "all", + any(target_os = "android", target_os = "linux", target_os = "fuchsia") + ))) + )] + #[deprecated = "Use `Socket::ip_transparent_v4` instead"] + pub fn ip_transparent(&self) -> io::Result { + self.ip_transparent_v4() + } + /// Get the value of the `IP_TRANSPARENT` option on this socket. /// - /// For more information about this option, see [`set_ip_transparent`]. + /// For more information about this option, see [`set_ip_transparent_v4`]. /// - /// [`set_ip_transparent`]: Socket::set_ip_transparent + /// [`set_ip_transparent_v4`]: crate::Socket::set_ip_transparent_v4 #[cfg(all( feature = "all", any(target_os = "android", target_os = "linux", target_os = "fuchsia") @@ -3114,13 +3131,30 @@ impl crate::Socket { any(target_os = "android", target_os = "linux", target_os = "fuchsia") ))) )] - pub fn ip_transparent(&self) -> io::Result { + pub fn ip_transparent_v4(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::IPPROTO_IP, libc::IP_TRANSPARENT) .map(|transparent| transparent != 0) } } + /// This method is deprecated, use [`crate::Socket::set_ip_transparent_v4`]. + #[cfg(all( + feature = "all", + any(target_os = "android", target_os = "linux", target_os = "fuchsia") + ))] + #[cfg_attr( + docsrs, + doc(cfg(all( + feature = "all", + any(target_os = "android", target_os = "linux", target_os = "fuchsia") + ))) + )] + #[deprecated = "Use `Socket::set_ip_transparent_v4` instead"] + pub fn set_ip_transparent(&self, transparent: bool) -> io::Result<()> { + self.set_ip_transparent_v4(transparent) + } + /// Set the value of the `IP_TRANSPARENT` option on this socket. /// /// Setting this boolean option enables transparent proxying @@ -3147,7 +3181,7 @@ impl crate::Socket { any(target_os = "android", target_os = "linux", target_os = "fuchsia") ))) )] - pub fn set_ip_transparent(&self, transparent: bool) -> io::Result<()> { + pub fn set_ip_transparent_v4(&self, transparent: bool) -> io::Result<()> { unsafe { setsockopt( self.as_raw(), diff --git a/tests/socket.rs b/tests/socket.rs index fa17376d..8b4e5f45 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1369,8 +1369,8 @@ test!( ))] test!( #[ignore = "setting `IP_TRANSPARENT` requires the `CAP_NET_ADMIN` capability (works when running as root)"] - ip_transparent, - set_ip_transparent(true) + ip_transparent_v4, + set_ip_transparent_v4(true) ); #[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))] test!( From 99d9851875a0f04e991782551b4e54bb672b846d Mon Sep 17 00:00:00 2001 From: cavivie Date: Fri, 2 Aug 2024 18:52:41 +0800 Subject: [PATCH 4/6] Add (set_)ip_transparent_v6 for target_os=android/linux --- src/sys/unix.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/socket.rs | 6 ++++++ 2 files changed, 54 insertions(+) diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 7c684e9a..c30d50ba 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -3191,6 +3191,54 @@ impl crate::Socket { ) } } + + /// Get the value of the `IPV6_TRANSPARENT` option on this socket. + /// + /// For more information about this option, see [`set_ip_transparent_v6`]. + /// + /// [`set_ip_transparent_v6`]: crate::Socket::set_ip_transparent_v6 + #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] + #[cfg_attr( + docsrs, + doc(cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))) + )] + pub fn ip_transparent_v6(&self) -> io::Result { + unsafe { + getsockopt::(self.as_raw(), libc::IPPROTO_IPV6, libc::IPV6_TRANSPARENT) + .map(|transparent| transparent != 0) + } + } + + /// Set the value of the `IPV6_TRANSPARENT` option on this socket. + /// + /// Setting this boolean option enables transparent proxying + /// on this socket. This socket option allows the calling + /// application to bind to a nonlocal IP address and operate + /// both as a client and a server with the foreign address as + /// the local endpoint. NOTE: this requires that routing be + /// set up in a way that packets going to the foreign address + /// are routed through the TProxy box (i.e., the system + /// hosting the application that employs the IPV6_TRANSPARENT + /// socket option). Enabling this socket option requires + /// superuser privileges (the `CAP_NET_ADMIN` capability). + /// + /// TProxy redirection with the iptables TPROXY target also + /// requires that this option be set on the redirected socket. + #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] + #[cfg_attr( + docsrs, + doc(cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))) + )] + pub fn set_ip_transparent_v6(&self, transparent: bool) -> io::Result<()> { + unsafe { + setsockopt( + self.as_raw(), + libc::IPPROTO_IPV6, + libc::IPV6_TRANSPARENT, + transparent as c_int, + ) + } + } } /// See [`Socket::dccp_available_ccids`]. diff --git a/tests/socket.rs b/tests/socket.rs index 8b4e5f45..7313f4fc 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1372,6 +1372,12 @@ test!( ip_transparent_v4, set_ip_transparent_v4(true) ); +#[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] +test!( + #[ignore = "setting `IPV6_TRANSPARENT` requires the `CAP_NET_ADMIN` capability (works when running as root)"] + ip_transparent_v6, + set_ip_transparent_v6(true) +); #[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))] test!( #[ignore = "setting `SO_MARK` requires the `CAP_NET_ADMIN` capability (works when running as root)"] From adc2b3a05d2d5b53cd61837374b09606f7c96d62 Mon Sep 17 00:00:00 2001 From: cavivie Date: Tue, 6 Aug 2024 21:03:16 +0800 Subject: [PATCH 5/6] Deprecate (set_)ip_freebind(_ipv6) in favour of (set_)ip_bindany_(v4|v6) --- src/sys/unix.rs | 175 ++++++++++++++++++++++++++++-------------------- tests/socket.rs | 21 ++++-- 2 files changed, 119 insertions(+), 77 deletions(-) diff --git a/src/sys/unix.rs b/src/sys/unix.rs index c30d50ba..dd24cce7 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -2285,11 +2285,7 @@ impl crate::Socket { } } - /// Get the value of the `IP_FREEBIND` option on this socket. - /// - /// For more information about this option, see [`set_freebind`]. - /// - /// [`set_freebind`]: crate::Socket::set_freebind + /// This method is deprecated, use [`crate::Socket::ip_bindany_v4`]. #[cfg(all( feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") @@ -2301,20 +2297,12 @@ impl crate::Socket { any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))) )] + #[deprecated = "Use `Socket::ip_bindany_v4` instead"] pub fn freebind(&self) -> io::Result { - unsafe { - getsockopt::(self.as_raw(), libc::SOL_IP, libc::IP_FREEBIND) - .map(|freebind| freebind != 0) - } + self.ip_bindany_v4() } - /// Set value for the `IP_FREEBIND` option on this socket. - /// - /// If enabled, this boolean option allows binding to an IP address that is - /// nonlocal or does not (yet) exist. This permits listening on a socket, - /// without requiring the underlying network interface or the specified - /// dynamic IP address to be up at the time that the application is trying - /// to bind to it. + /// This method is deprecated, use [`crate::Socket::set_ip_bindany_v4`]. #[cfg(all( feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") @@ -2326,80 +2314,31 @@ impl crate::Socket { any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))) )] + #[deprecated = "Use `Socket::set_ip_bindany_v4` instead"] pub fn set_freebind(&self, freebind: bool) -> io::Result<()> { - unsafe { - setsockopt( - self.as_raw(), - libc::SOL_IP, - libc::IP_FREEBIND, - freebind as c_int, - ) - } + self.set_ip_bindany_v4(freebind) } - /// Get the value of the `IPV6_FREEBIND` option on this socket. - /// - /// This is an IPv6 counterpart of `IP_FREEBIND` socket option on - /// Android/Linux. For more information about this option, see - /// [`set_freebind`]. - /// - /// [`set_freebind`]: crate::Socket::set_freebind + /// This method is deprecated, use [`crate::Socket::ip_bindany_v6`]. #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] #[cfg_attr( docsrs, doc(cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))) )] + #[deprecated = "Use `Socket::ip_bindany_v6` instead"] pub fn freebind_ipv6(&self) -> io::Result { - unsafe { - getsockopt::(self.as_raw(), libc::SOL_IPV6, libc::IPV6_FREEBIND) - .map(|freebind| freebind != 0) - } + self.ip_bindany_v6() } - /// Set value for the `IPV6_FREEBIND` option on this socket. - /// - /// This is an IPv6 counterpart of `IP_FREEBIND` socket option on - /// Android/Linux. For more information about this option, see - /// [`set_freebind`]. - /// - /// [`set_freebind`]: crate::Socket::set_freebind - /// - /// # Examples - /// - /// On Linux: - /// - /// ``` - /// use socket2::{Domain, Socket, Type}; - /// use std::io::{self, Error, ErrorKind}; - /// - /// fn enable_freebind(socket: &Socket) -> io::Result<()> { - /// match socket.domain()? { - /// Domain::IPV4 => socket.set_freebind(true)?, - /// Domain::IPV6 => socket.set_freebind_ipv6(true)?, - /// _ => return Err(Error::new(ErrorKind::Other, "unsupported domain")), - /// }; - /// Ok(()) - /// } - /// - /// # fn main() -> io::Result<()> { - /// # let socket = Socket::new(Domain::IPV6, Type::STREAM, None)?; - /// # enable_freebind(&socket) - /// # } - /// ``` + /// This method is deprecated, use [`crate::Socket::set_ip_bindany_v6`]. #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] #[cfg_attr( docsrs, doc(cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))) )] + #[deprecated = "Use `Socket::set_ip_bindany_v6` instead"] pub fn set_freebind_ipv6(&self, freebind: bool) -> io::Result<()> { - unsafe { - setsockopt( - self.as_raw(), - libc::SOL_IPV6, - libc::IPV6_FREEBIND, - freebind as c_int, - ) - } + self.set_ip_bindany_v6(freebind) } /// Get the value for the `SO_ORIGINAL_DST` option on this socket. @@ -3239,6 +3178,96 @@ impl crate::Socket { ) } } + + /// Get the value of the bind-any-like option on this socket. + /// The option is that `IP_FREEBIND` on Android/Fuchisa/Linux, + /// `IP_BINDANY` on FreeBSD and `SO_BINDANY` on FreeBSD. + /// + /// For more information about this option, see [`set_ip_bindany_v4`]. + /// + /// [`set_ip_bindany_v4`]: crate::Socket::set_ip_bindany_v4 + #[cfg(all( + feature = "all", + any(target_os = "android", target_os = "fuchsia", target_os = "linux") + ))] + #[cfg_attr( + docsrs, + doc(cfg(all( + feature = "all", + any(target_os = "android", target_os = "fuchsia", target_os = "linux") + ))) + )] + pub fn ip_bindany_v4(&self) -> io::Result { + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + let (level, opt) = (libc::SOL_IP, libc::IP_FREEBIND); + + unsafe { getsockopt::(self.as_raw(), level, opt).map(|bindany| bindany != 0) } + } + + /// Set the value of the bind-any-like option on this socket. + /// The option is that `IP_FREEBIND` on Android/Fuchisa/Linux, + /// `IP_BINDANY` on FreeBSD and `SO_BINDANY` on FreeBSD. + /// + /// The option allows the socket to be bound to addresses which are not + /// nonlocal. This permits listening on a socket, without requiring the + /// underlying network interface or the specified dynamic IP address to + /// be up at the time that the application is trying to bind to it. + #[cfg(all( + feature = "all", + any(target_os = "android", target_os = "fuchsia", target_os = "linux") + ))] + #[cfg_attr( + docsrs, + doc(cfg(all( + feature = "all", + any(target_os = "android", target_os = "fuchsia", target_os = "linux") + ))) + )] + pub fn set_ip_bindany_v4(&self, bindany: bool) -> io::Result<()> { + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + let (level, opt) = (libc::SOL_IP, libc::IP_FREEBIND); + + unsafe { setsockopt(self.as_raw(), level, opt, bindany as c_int) } + } + + /// Get the value of the bind-any-like option on this socket. + /// The option is that `IPV6_FREEBIND` on Android/Linux, + /// `IPV6_BINDANY` on FreeBSD and `SO_BINDANY` on FreeBSD. + /// + /// For more information about this option, see [`set_ip_bindany_v6`]. + /// + /// [`set_ip_bindany_v6`]: crate::Socket::set_ip_bindany_v6 + #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] + #[cfg_attr( + docsrs, + doc(cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))) + )] + pub fn ip_bindany_v6(&self) -> io::Result { + #[cfg(any(target_os = "android", target_os = "linux"))] + let (level, opt) = (libc::SOL_IPV6, libc::IPV6_FREEBIND); + + unsafe { getsockopt::(self.as_raw(), level, opt).map(|bindany| bindany != 0) } + } + + /// Set the value of the bind-any-like option on this socket. + /// The option is that `IPV6_FREEBIND` on Android/Linux, + /// `IPV6_BINDANY` on FreeBSD and `SO_BINDANY` on FreeBSD. + /// + /// This is an IPv6 counterpart of `set_ip_bindany_v4` on a socket. + /// For more information about this option, see [`set_ip_bindany_v4`]. + /// + /// [`set_ip_bindany_v4`]: crate::Socket::set_ip_bindany_v4 + #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] + #[cfg_attr( + docsrs, + doc(cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))) + )] + pub fn set_ip_bindany_v6(&self, bindany: bool) -> io::Result<()> { + #[cfg(any(target_os = "android", target_os = "linux"))] + let (level, opt) = (libc::SOL_IPV6, libc::IPV6_FREEBIND); + + unsafe { setsockopt(self.as_raw(), level, opt, bindany as c_int) } + } } /// See [`Socket::dccp_available_ccids`]. diff --git a/tests/socket.rs b/tests/socket.rs index 7313f4fc..4cf59a2a 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1405,10 +1405,23 @@ test!( set_read_timeout(Some(Duration::from_secs(10))) ); test!(keepalive, set_keepalive(true)); -#[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))] -test!(freebind, set_freebind(true)); -#[cfg(all(feature = "all", target_os = "linux"))] -test!(IPv6 freebind_ipv6, set_freebind_ipv6(true)); +#[cfg(all( + feature = "all", + any( + target_os = "android", + target_os = "fuchsia", + target_os = "linux" + ) +))] +test!(ip_bindany_v4, set_ip_bindany_v4(true)); +#[cfg(all( + feature = "all", + any( + target_os = "android", + target_os = "linux" + ) +))] +test!(IPv6 ip_bindany_v6, set_ip_bindany_v6(true)); test!(IPv4 ttl, set_ttl(40)); From 037eac54bc5cfaf0c655fef8d0732783dd2a1c5d Mon Sep 17 00:00:00 2001 From: cavivie Date: Tue, 6 Aug 2024 21:03:16 +0800 Subject: [PATCH 6/6] Add target_os=freebsd/openbsd for (set_)ip_bindany_(v4|v6) --- src/sys/unix.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++----- tests/socket.rs | 8 +++-- 2 files changed, 86 insertions(+), 10 deletions(-) diff --git a/src/sys/unix.rs b/src/sys/unix.rs index dd24cce7..e97923da 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -3188,18 +3188,34 @@ impl crate::Socket { /// [`set_ip_bindany_v4`]: crate::Socket::set_ip_bindany_v4 #[cfg(all( feature = "all", - any(target_os = "android", target_os = "fuchsia", target_os = "linux") + any( + target_os = "android", + target_os = "fuchsia", + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd" + ) ))] #[cfg_attr( docsrs, doc(cfg(all( feature = "all", - any(target_os = "android", target_os = "fuchsia", target_os = "linux") + any( + target_os = "android", + target_os = "fuchsia", + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd" + ) ))) )] pub fn ip_bindany_v4(&self) -> io::Result { #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] let (level, opt) = (libc::SOL_IP, libc::IP_FREEBIND); + #[cfg(target_os = "freebsd")] + let (level, opt) = (libc::IPPROTO_IP, libc::IP_BINDANY); + #[cfg(target_os = "openbsd")] + let (level, opt) = (libc::SOL_SOCKET, libc::SO_BINDANY); unsafe { getsockopt::(self.as_raw(), level, opt).map(|bindany| bindany != 0) } } @@ -3214,18 +3230,34 @@ impl crate::Socket { /// be up at the time that the application is trying to bind to it. #[cfg(all( feature = "all", - any(target_os = "android", target_os = "fuchsia", target_os = "linux") + any( + target_os = "android", + target_os = "fuchsia", + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd" + ) ))] #[cfg_attr( docsrs, doc(cfg(all( feature = "all", - any(target_os = "android", target_os = "fuchsia", target_os = "linux") + any( + target_os = "android", + target_os = "fuchsia", + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd" + ) ))) )] pub fn set_ip_bindany_v4(&self, bindany: bool) -> io::Result<()> { #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] let (level, opt) = (libc::SOL_IP, libc::IP_FREEBIND); + #[cfg(target_os = "freebsd")] + let (level, opt) = (libc::IPPROTO_IP, libc::IP_BINDANY); + #[cfg(target_os = "openbsd")] + let (level, opt) = (libc::SOL_SOCKET, libc::SO_BINDANY); unsafe { setsockopt(self.as_raw(), level, opt, bindany as c_int) } } @@ -3237,14 +3269,34 @@ impl crate::Socket { /// For more information about this option, see [`set_ip_bindany_v6`]. /// /// [`set_ip_bindany_v6`]: crate::Socket::set_ip_bindany_v6 - #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] + #[cfg(all( + feature = "all", + any( + target_os = "android", + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd" + ) + ))] #[cfg_attr( docsrs, - doc(cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))) + doc(cfg(all( + feature = "all", + any( + target_os = "android", + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd" + ) + ))) )] pub fn ip_bindany_v6(&self) -> io::Result { #[cfg(any(target_os = "android", target_os = "linux"))] let (level, opt) = (libc::SOL_IPV6, libc::IPV6_FREEBIND); + #[cfg(target_os = "freebsd")] + let (level, opt) = (libc::IPPROTO_IPV6, libc::IPV6_BINDANY); + #[cfg(target_os = "openbsd")] + let (level, opt) = (libc::SOL_SOCKET, libc::SO_BINDANY); unsafe { getsockopt::(self.as_raw(), level, opt).map(|bindany| bindany != 0) } } @@ -3257,14 +3309,34 @@ impl crate::Socket { /// For more information about this option, see [`set_ip_bindany_v4`]. /// /// [`set_ip_bindany_v4`]: crate::Socket::set_ip_bindany_v4 - #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] + #[cfg(all( + feature = "all", + any( + target_os = "android", + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd" + ) + ))] #[cfg_attr( docsrs, - doc(cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))) + doc(cfg(all( + feature = "all", + any( + target_os = "android", + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd" + ) + ))) )] pub fn set_ip_bindany_v6(&self, bindany: bool) -> io::Result<()> { #[cfg(any(target_os = "android", target_os = "linux"))] let (level, opt) = (libc::SOL_IPV6, libc::IPV6_FREEBIND); + #[cfg(target_os = "freebsd")] + let (level, opt) = (libc::IPPROTO_IPV6, libc::IPV6_BINDANY); + #[cfg(target_os = "openbsd")] + let (level, opt) = (libc::SOL_SOCKET, libc::SO_BINDANY); unsafe { setsockopt(self.as_raw(), level, opt, bindany as c_int) } } diff --git a/tests/socket.rs b/tests/socket.rs index 4cf59a2a..7f1fe963 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1410,7 +1410,9 @@ test!(keepalive, set_keepalive(true)); any( target_os = "android", target_os = "fuchsia", - target_os = "linux" + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd" ) ))] test!(ip_bindany_v4, set_ip_bindany_v4(true)); @@ -1418,7 +1420,9 @@ test!(ip_bindany_v4, set_ip_bindany_v4(true)); feature = "all", any( target_os = "android", - target_os = "linux" + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd" ) ))] test!(IPv6 ip_bindany_v6, set_ip_bindany_v6(true));