From c93cdcc25fd3de7ef20515b9c16ed2b5771ed268 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Tue, 12 Mar 2024 15:46:35 +0100 Subject: [PATCH 01/33] Add MSG_CONFIRM and MSG_DONTROUTE to RecvFlags --- src/sys/unix.rs | 35 +++++++++++++++++++++++++++++++++++ tests/socket.rs | 4 ++++ 2 files changed, 39 insertions(+) diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 805b6d55..562cd60f 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -573,6 +573,37 @@ impl RecvFlags { pub const fn is_out_of_band(self) -> bool { self.0 & libc::MSG_OOB != 0 } + + /// Check if the confirm flag is set. + /// + /// This is used by SocketCAN to indicate a frame was sent via the + /// socket it is received on. This flag can be interpreted as a + /// 'transmission confirmation'. + /// + /// On Unix this corresponds to the `MSG_CONFIRM` flag. + #[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 const fn is_confirm(self) -> bool { + self.0 & libc::MSG_CONFIRM != 0 + } + + /// Check if the don't route flag is set. + /// + /// This is used by SocketCAN to indicate a frame was created + /// on the local host. + /// + /// On Unix this corresponds to the `MSG_DONTROUTE` flag. + #[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 const fn is_dontroute(self) -> bool { + self.0 & libc::MSG_DONTROUTE != 0 + } } #[cfg(not(target_os = "redox"))] @@ -584,6 +615,10 @@ impl std::fmt::Debug for RecvFlags { s.field("is_out_of_band", &self.is_out_of_band()); #[cfg(not(target_os = "espidf"))] s.field("is_truncated", &self.is_truncated()); + #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] + s.field("is_confirm", &self.is_confirm()); + #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] + s.field("is_dontroute", &self.is_dontroute()); s.finish() } } diff --git a/tests/socket.rs b/tests/socket.rs index a31255dd..1c83321a 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -731,6 +731,10 @@ fn send_from_recv_to_vectored() { #[cfg(all(unix, not(target_os = "redox")))] assert_eq!(flags.is_out_of_band(), false); assert_eq!(flags.is_truncated(), false); + #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] + assert_eq!(flags.is_confirm(), false); + #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] + assert_eq!(flags.is_dontroute(), false); assert_eq!( addr.as_socket_ipv6().unwrap(), addr_a.as_socket_ipv6().unwrap() From 21ba6609efe09a7e27d62d2c29ff61bab88b970d Mon Sep 17 00:00:00 2001 From: Toby Lawrence Date: Mon, 15 Apr 2024 17:39:07 +0000 Subject: [PATCH 02/33] Add MsgHdrMut::control_len to get how much of control buffer was filled. --- src/lib.rs | 9 +++++++++ src/sys/unix.rs | 5 +++++ src/sys/windows.rs | 4 ++++ 3 files changed, 18 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 4f6bd789..89dce26e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -719,6 +719,15 @@ impl<'addr, 'bufs, 'control> MsgHdrMut<'addr, 'bufs, 'control> { pub fn flags(&self) -> RecvFlags { sys::msghdr_flags(&self.inner) } + + /// Gets the length of the control buffer. + /// + /// Can be used to determine how much, if any, of the control buffer was filled by `recvmsg`. + /// + /// Corresponds to `msg_controllen` on Unix and `Control.len` on Windows. + pub fn control_len(&self) -> usize { + sys::msghdr_control_len(&self.inner) + } } #[cfg(not(target_os = "redox"))] diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 562cd60f..90d3eb1a 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -738,6 +738,11 @@ pub(crate) fn msghdr_flags(msg: &msghdr) -> RecvFlags { RecvFlags(msg.msg_flags) } +#[cfg(not(target_os = "redox"))] +pub(crate) fn msghdr_control_len(msg: &msghdr) -> usize { + msg.msg_controllen as _ +} + /// Unix only API. impl SockAddr { /// Constructs a `SockAddr` with the family `AF_VSOCK` and the provided CID/port. diff --git a/src/sys/windows.rs b/src/sys/windows.rs index 4c5d9879..11f2b7b0 100644 --- a/src/sys/windows.rs +++ b/src/sys/windows.rs @@ -215,6 +215,10 @@ pub(crate) fn msghdr_flags(msg: &msghdr) -> RecvFlags { RecvFlags(msg.dwFlags as c_int) } +pub(crate) fn msghdr_control_len(msg: &msghdr) -> usize { + msg.Control.len as _ +} + fn init() { static INIT: Once = Once::new(); From 630c8a73709027c7bfbd9850fe44541e3c62dec0 Mon Sep 17 00:00:00 2001 From: Toby Lawrence Date: Mon, 15 Apr 2024 19:44:24 +0000 Subject: [PATCH 03/33] Add Socket::passcred/set_passcred for working with SO_PASSCRED. --- src/socket.rs | 31 +++++++++++++++++++++++++++++++ src/sys/unix.rs | 2 ++ 2 files changed, 33 insertions(+) diff --git a/src/socket.rs b/src/socket.rs index 3291707c..21bcfcb2 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -965,6 +965,37 @@ impl Socket { } } + /// Get value for the `SO_PASSCRED` option on this socket. + /// + /// For more information about this option, see [`set_passcred`]. + /// + /// [`set_passcred`]: Socket::set_passcred + #[cfg(all(unix, target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all(unix, target_os = "linux"))))] + pub fn passcred(&self) -> io::Result { + unsafe { + getsockopt::(self.as_raw(), sys::SOL_SOCKET, sys::SO_PASSCRED) + .map(|passcred| passcred != 0) + } + } + + /// Set value for the `SO_PASSCRED` option on this socket. + /// + /// If this option is enabled, enables the receiving of the `SCM_CREDENTIALS` + /// control messages. + #[cfg(all(unix, target_os = "linux"))] + #[cfg_attr(docsrs, doc(cfg(all(unix, target_os = "linux"))))] + pub fn set_passcred(&self, passcred: bool) -> io::Result<()> { + unsafe { + setsockopt( + self.as_raw(), + sys::SOL_SOCKET, + sys::SO_PASSCRED, + passcred as c_int, + ) + } + } + /// Get value for the `SO_RCVBUF` option on this socket. /// /// For more information about this option, see [`set_recv_buffer_size`]. diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 90d3eb1a..95869f52 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -179,6 +179,8 @@ pub(crate) use libc::{ SO_BROADCAST, SO_ERROR, SO_KEEPALIVE, SO_RCVBUF, SO_RCVTIMEO, SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO, SO_TYPE, TCP_NODELAY, }; +#[cfg(target_os = "linux")] +pub(crate) use libc::SO_PASSCRED; #[cfg(not(any( target_os = "dragonfly", target_os = "haiku", From 6923954ce066e26a1d726ba2ca9d2b2c2176f3a2 Mon Sep 17 00:00:00 2001 From: Toby Lawrence Date: Wed, 17 Apr 2024 00:08:30 +0000 Subject: [PATCH 04/33] Add test for Socket::passcred/set_passcred and fix formatting. --- src/sys/unix.rs | 4 ++-- tests/socket.rs | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 95869f52..51ef4a5d 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -172,6 +172,8 @@ pub(crate) use libc::SO_LINGER; target_os = "watchos", ))] pub(crate) use libc::SO_LINGER_SEC as SO_LINGER; +#[cfg(target_os = "linux")] +pub(crate) use libc::SO_PASSCRED; pub(crate) use libc::{ ip_mreq as IpMreq, linger, IPPROTO_IP, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, IPV6_MULTICAST_IF, IPV6_MULTICAST_LOOP, IPV6_UNICAST_HOPS, IPV6_V6ONLY, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, @@ -179,8 +181,6 @@ pub(crate) use libc::{ SO_BROADCAST, SO_ERROR, SO_KEEPALIVE, SO_RCVBUF, SO_RCVTIMEO, SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO, SO_TYPE, TCP_NODELAY, }; -#[cfg(target_os = "linux")] -pub(crate) use libc::SO_PASSCRED; #[cfg(not(any( target_os = "dragonfly", target_os = "haiku", diff --git a/tests/socket.rs b/tests/socket.rs index 1c83321a..89b79f5f 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1680,3 +1680,19 @@ fn cookie() { Err(err) => panic!("Could not get socket cookie a second time, err: {err}"), } } + +#[cfg(all(unix, target_os = "linux"))] +#[test] +fn set_passcred() { + let socket = Socket::new(Domain::UNIX, Type::DGRAM, None).unwrap(); + assert!(!socket.passcred().unwrap()); + + socket.set_passcred(true).unwrap(); + assert!(socket.passcred().unwrap()); + + let socket = Socket::new(Domain::UNIX, Type::STREAM, None).unwrap(); + assert!(!socket.passcred().unwrap()); + + socket.set_passcred(true).unwrap(); + assert!(socket.passcred().unwrap()); +} From 8685db561c95f879d0ebba3153634bb17c75590d Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sun, 28 Apr 2024 15:20:18 +0200 Subject: [PATCH 05/33] Use consistent language in change log --- CHANGELOG.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49f41310..8b9f25fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,21 +1,21 @@ # 0.5.6 -* Add `Socket::(set_)multicast_all_v{4,6}` +* Added `Socket::(set_)multicast_all_v{4,6}` (https://github.com/rust-lang/socket2/pull/485 and (https://github.com/rust-lang/socket2/pull/486). -* Add support for GNU/Hurd +* Added support for GNU/Hurd (https://github.com/rust-lang/socket2/pull/474). -* Fix compilation on Haiku +* Fixes compilation on Haiku (https://github.com/rust-lang/socket2/pull/479 and (https://github.com/rust-lang/socket2/pull/482). -* Fix compilation on OpenHarmony +* Fixes compilation on OpenHarmony (https://github.com/rust-lang/socket2/pull/491). * Update to window-sys v0.52 (https://github.com/rust-lang/socket2/pull/480). # 0.5.5 -* Add support for Vita +* Added support for Vita (https://github.com/rust-lang/socket2/pull/465). # 0.5.4 @@ -35,7 +35,7 @@ (https://github.com/rust-lang/socket2/pull/442). * Added `Protocol::DIVERT` on FreeBSD and OpenBSD (https://github.com/rust-lang/socket2/pull/448). -* Add `Socket::protocol` for Windows (using `WSAPROTOCOL_INFOW`) +* Added `Socket::protocol` for Windows (using `WSAPROTOCOL_INFOW`) (https://github.com/rust-lang/socket2/pull/470). * `From` for `SockAddr ` nows sets `ss_len` on platforms that have the fields (most BSDs) @@ -53,7 +53,7 @@ # 0.5.2 -* Add Unix socket methods to `SockAddr` +* Added Unix socket methods to `SockAddr` (https://github.com/rust-lang/socket2/pull/403 and https://github.com/rust-lang/socket2/pull/429). * Added `SockAddr::as_storage` @@ -167,9 +167,9 @@ * Fixed compilation with the `all` on QNX Neutrino (https://github.com/rust-lang/socket2/pull/419). -* Add support for ESP-IDF +* Added support for ESP-IDF (https://github.com/rust-lang/socket2/pull/455). -* Add support for Vita +* Added support for Vita (https://github.com/rust-lang/socket2/pull/475). # 0.4.9 @@ -181,7 +181,7 @@ This release was broken for Windows. -* Add `Socket::peek_sender` (backport) +* Added `Socket::peek_sender` (backport) (https://github.com/rust-lang/socket2/pull/404). # 0.4.7 @@ -200,7 +200,7 @@ This release was broken for Windows. (https://github.com/rust-lang/socket2/pull/307). * Derive Clone for SockAddr (https://github.com/rust-lang/socket2/pull/311). -* Fix cfg attributes for Fuchsia +* Fixes cfg attributes for Fuchsia (https://github.com/rust-lang/socket2/pull/314). # 0.4.5 (yanked) @@ -219,7 +219,7 @@ This release was broken for Windows. ## Fixed -* Fix OpenBSD build +* OpenBSD build (https://github.com/rust-lang/socket2/pull/291). # 0.4.4 @@ -264,13 +264,13 @@ This release was broken for Windows. ## Added -* Add `SockAddr::new` +* Added `SockAddr::new` * Support for `TCP_USER_TIMEOUT`. * Support for `IP_BOUND_IF`. * Support for `IP_TRANSPARENT`. * Enable `Socket::type` on all platforms. * Support for uclibc (for Haiku support). -* Add DragonFly support for TCP keepalive (`KEEPINTVL`/`KEEPCNT`). +* Added DragonFly support for TCP keepalive (`KEEPINTVL`/`KEEPCNT`). * Documentation for proper use of `SockRef::from`, and the improper use. * Assertion in `SockRef::from` to ensure the raw socket valid. From c8146aa5bb839004208bfd89267ec61a7774386e Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sun, 28 Apr 2024 15:23:13 +0200 Subject: [PATCH 06/33] Release v0.5.7 --- CHANGELOG.md | 13 +++++++++++-- Cargo.toml | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b9f25fa..b90e67c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,22 @@ +# 0.5.7 + +* Added `Socket::(set_)passcred` + (https://github.com/rust-lang/socket2/pull/506). +* Added `RecvFlags::is_confirm` and `RecvFlags::is_dontroute` + (https://github.com/rust-lang/socket2/pull/499). +* Added `MsgHdrMut::control_len` + (https://github.com/rust-lang/socket2/pull/505). + # 0.5.6 * Added `Socket::(set_)multicast_all_v{4,6}` (https://github.com/rust-lang/socket2/pull/485 and - (https://github.com/rust-lang/socket2/pull/486). + https://github.com/rust-lang/socket2/pull/486). * Added support for GNU/Hurd (https://github.com/rust-lang/socket2/pull/474). * Fixes compilation on Haiku (https://github.com/rust-lang/socket2/pull/479 and - (https://github.com/rust-lang/socket2/pull/482). + https://github.com/rust-lang/socket2/pull/482). * Fixes compilation on OpenHarmony (https://github.com/rust-lang/socket2/pull/491). * Update to window-sys v0.52 diff --git a/Cargo.toml b/Cargo.toml index 96cc5f13..8ef85ebc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "socket2" -version = "0.5.6" +version = "0.5.7" authors = [ "Alex Crichton ", "Thomas de Zeeuw " From 127a4c919d5beba876ce2b13a2ba1dda94486b55 Mon Sep 17 00:00:00 2001 From: milan Date: Fri, 24 May 2024 12:15:05 +0200 Subject: [PATCH 07/33] fix typos Fixes minor errors in comments and docs. Specifically, this commit corrects "Futhermore" to "Furthermore" and adds a comma after uses of "Furthermore" as an introductory phrase. --- src/sockaddr.rs | 2 +- src/socket.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sockaddr.rs b/src/sockaddr.rs index 6df22fdc..2f4b40ed 100644 --- a/src/sockaddr.rs +++ b/src/sockaddr.rs @@ -258,7 +258,7 @@ impl SockAddr { /// Returns the initialised storage bytes. fn as_bytes(&self) -> &[u8] { // SAFETY: `self.storage` is a C struct which can always be treated a - // slice of bytes. Futhermore we ensure we don't read any unitialised + // slice of bytes. Furthermore, we ensure we don't read any unitialised // bytes by using `self.len`. unsafe { std::slice::from_raw_parts(self.as_ptr().cast(), self.len as usize) } } diff --git a/src/socket.rs b/src/socket.rs index 21bcfcb2..19f269cf 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1053,7 +1053,7 @@ impl Socket { /// Set value for the `SO_REUSEADDR` option on this socket. /// - /// This indicates that futher calls to `bind` may allow reuse of local + /// This indicates that further calls to `bind` may allow reuse of local /// addresses. For IPv4 sockets this means that a socket may bind even when /// there's a socket already listening on this port. pub fn set_reuse_address(&self, reuse: bool) -> io::Result<()> { @@ -2143,7 +2143,7 @@ impl Read for Socket { #[cfg(not(target_os = "redox"))] fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { // Safety: both `IoSliceMut` and `MaybeUninitSlice` promise to have the - // same layout, that of `iovec`/`WSABUF`. Furthermore `recv_vectored` + // same layout, that of `iovec`/`WSABUF`. Furthermore, `recv_vectored` // promises to not write unitialised bytes to the `bufs` and pass it // directly to the `recvmsg` system call, so this is safe. let bufs = unsafe { &mut *(bufs as *mut [IoSliceMut<'_>] as *mut [MaybeUninitSlice<'_>]) }; From 6a13053e528fe1bbbfff85461589bafc7425f7b0 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Fri, 24 May 2024 12:44:32 +0200 Subject: [PATCH 08/33] Ignore clippy new_without_default Not needed for TcpKeepalive. --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index 89dce26e..c3161d63 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -455,6 +455,7 @@ pub struct TcpKeepalive { impl TcpKeepalive { /// Returns a new, empty set of TCP keepalive parameters. + #[allow(clippy::new_without_default)] pub const fn new() -> TcpKeepalive { TcpKeepalive { time: None, From 7fe1bff392a23a84635dfaa314820e868930ad8f Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Tue, 18 Jun 2024 06:31:55 -0300 Subject: [PATCH 09/33] Add: header_included_v6() and set_header_included_v6() Also, deprecate header_included() and set_header_included() in favor of header_included_v4() and set_header_included_v4(). --- src/socket.rs | 74 +++++++++++++++++++++++++++++++++++++++++++++++-- tests/socket.rs | 30 ++++++++++++++++++-- 2 files changed, 99 insertions(+), 5 deletions(-) diff --git a/src/socket.rs b/src/socket.rs index 19f269cf..e0ccf8e4 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1138,6 +1138,16 @@ const fn into_linger(duration: Option) -> sys::linger { /// * Linux: /// * Windows: impl Socket { + /// This method is deprecated, use [`crate::Socket::header_included_v4`]. + #[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))] + #[cfg_attr( + docsrs, + doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) + )] + #[deprecated = "Use `Socket::header_included_v4` instead"] + pub fn header_included(&self) -> io::Result { + self.header_included_v4() + } /// Get the value of the `IP_HDRINCL` option on this socket. /// /// For more information about this option, see [`set_header_included`]. @@ -1148,13 +1158,28 @@ impl Socket { docsrs, doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) )] - pub fn header_included(&self) -> io::Result { + pub fn header_included_v4(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_IP, sys::IP_HDRINCL) .map(|included| included != 0) } } + /// This method is deprecated, use [`crate::Socket::set_header_included_v4`]. + #[cfg_attr( + any(target_os = "fuchsia", target_os = "illumos", target_os = "solaris"), + allow(rustdoc::broken_intra_doc_links) + )] + #[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))] + #[cfg_attr( + docsrs, + doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) + )] + #[deprecated = "Use `Socket::set_header_included_v4` instead"] + pub fn set_header_included(&self, included: bool) -> io::Result<()> { + self.set_header_included_v4(included) + } + /// Set the value of the `IP_HDRINCL` option on this socket. /// /// If enabled, the user supplies an IP header in front of the user data. @@ -1175,7 +1200,7 @@ impl Socket { docsrs, doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) )] - pub fn set_header_included(&self, included: bool) -> io::Result<()> { + pub fn set_header_included_v4(&self, included: bool) -> io::Result<()> { unsafe { setsockopt( self.as_raw(), @@ -1651,6 +1676,51 @@ impl Socket { /// * Linux: /// * Windows: impl Socket { + /// Get the value of the `IP_HDRINCL` option on this socket. + /// + /// For more information about this option, see [`set_header_included`]. + /// + /// [`set_header_included`]: Socket::set_header_included + #[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))] + #[cfg_attr( + docsrs, + doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) + )] + pub fn header_included_v6(&self) -> io::Result { + unsafe { + getsockopt::(self.as_raw(), sys::IPPROTO_IPV6, sys::IP_HDRINCL) + .map(|included| included != 0) + } + } + + /// Set the value of the `IP_HDRINCL` option on this socket. + /// + /// If enabled, the user supplies an IP header in front of the user data. + /// Valid only for [`SOCK_RAW`] sockets; see [raw(7)] for more information. + /// When this flag is enabled, the values set by `IP_OPTIONS` are ignored. + /// + /// [`SOCK_RAW`]: Type::RAW + /// [raw(7)]: https://man7.org/linux/man-pages/man7/raw.7.html + #[cfg_attr( + any(target_os = "fuchsia", target_os = "illumos", target_os = "solaris"), + allow(rustdoc::broken_intra_doc_links) + )] + #[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))] + #[cfg_attr( + docsrs, + doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) + )] + pub fn set_header_included_v6(&self, included: bool) -> io::Result<()> { + unsafe { + setsockopt( + self.as_raw(), + sys::IPPROTO_IPV6, + sys::IP_HDRINCL, + included as c_int, + ) + } + } + /// Join a multicast group using `IPV6_ADD_MEMBERSHIP` option on this socket. /// /// Some OSs use `IPV6_JOIN_GROUP` for this option. diff --git a/tests/socket.rs b/tests/socket.rs index 89b79f5f..8e22542d 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1539,14 +1539,38 @@ fn header_included() { }; let initial = socket - .header_included() + .header_included_v4() .expect("failed to get initial value"); assert_eq!(initial, false, "initial value and argument are the same"); socket - .set_header_included(true) + .set_header_included_v4(true) .expect("failed to set option"); - let got = socket.header_included().expect("failed to get value"); + let got = socket.header_included_v4().expect("failed to get value"); + assert_eq!(got, true, "set and get values differ"); +} + +#[test] +#[cfg(all(feature = "all", not(target_os = "redox")))] +fn header_included_ipv6() { + let socket = match Socket::new(Domain::IPV6, Type::RAW, None) { + Ok(socket) => socket, + // Need certain permissions to create a raw sockets. + Err(ref err) if err.kind() == io::ErrorKind::PermissionDenied => return, + #[cfg(unix)] + Err(ref err) if err.raw_os_error() == Some(libc::EPROTONOSUPPORT) => return, + Err(err) => panic!("unexpected error creating socket: {}", err), + }; + + let initial = socket + .header_included_v6() + .expect("failed to get initial value"); + assert_eq!(initial, false, "initial value and argument are the same"); + + socket + .set_header_included_v6(true) + .expect("failed to set option"); + let got = socket.header_included_v6().expect("failed to get value"); assert_eq!(got, true, "set and get values differ"); } From c802777685d586b6e87cdf2a1ec97bba6338b96d Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Wed, 19 Jun 2024 09:16:51 +0200 Subject: [PATCH 10/33] Merge Check, CheckTier3, Docs and DocsTier3 CI jobs And expand the amount of targets we check. Instead of getting the target setup twice, one for the cargo check run and another for cargo doc, do it once and check both. --- .github/workflows/main.yml | 96 +++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0d83a0e5..6ff17f92 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -51,35 +51,63 @@ jobs: - name: Check formatting run: cargo fmt --all -- --check Check: - name: Check runs-on: ubuntu-latest + timeout-minutes: 10 strategy: fail-fast: false matrix: - target: ["aarch64-apple-ios", "aarch64-linux-android", "x86_64-apple-darwin", "x86_64-unknown-fuchsia", "x86_64-pc-windows-msvc", "x86_64-pc-solaris", "x86_64-unknown-freebsd", "x86_64-unknown-illumos", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl", "x86_64-unknown-netbsd", "x86_64-unknown-redox", "armv7-linux-androideabi", "i686-linux-android"] - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - targets: ${{ matrix.target }} - - uses: taiki-e/install-action@cargo-hack - - name: Run check - run: cargo hack check --feature-powerset --all-targets --examples --bins --tests --target ${{ matrix.target }} - CheckTier3: - name: Check - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - target: ["armv7-sony-vita-newlibeabihf", "i686-unknown-hurd-gnu"] + target: + - aarch64-apple-darwin + - aarch64-apple-ios + - aarch64-apple-tvos + - aarch64-apple-visionos + - aarch64-apple-watchos + - aarch64-linux-android + - aarch64-unknown-freebsd + - aarch64-unknown-hermit + - aarch64-unknown-linux-gnu + - aarch64-unknown-linux-musl + - aarch64-unknown-netbsd + - aarch64-unknown-nto-qnx710 + - aarch64-unknown-openbsd + - aarch64-unknown-redox + - arm-linux-androideabi + - arm64_32-apple-watchos + - armv7-linux-androideabi + - armv7-sony-vita-newlibeabihf + - i686-linux-android + - i686-unknown-hurd-gnu + - i686-unknown-linux-gnu + - riscv32imc-esp-espidf + - sparcv9-sun-solaris + - wasm32-wasi + - x86_64-apple-darwin + - x86_64-apple-ios + - x86_64-pc-nto-qnx710 + - x86_64-pc-solaris + - x86_64-pc-windows-gnu + - x86_64-pc-windows-msvc + - x86_64-unknown-dragonfly + - x86_64-unknown-freebsd + - x86_64-unknown-fuchsia + - x86_64-unknown-haiku + - x86_64-unknown-hermit + - x86_64-unknown-illumos + - x86_64-unknown-linux-gnu + - x86_64-unknown-linux-musl + - x86_64-unknown-netbsd + - x86_64-unknown-openbsd + - x86_64-unknown-redox steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@nightly with: - components: "rust-src" + components: rust-src - uses: taiki-e/install-action@cargo-hack - - name: Run check - run: cargo hack check -Z build-std=std,panic_abort --feature-powerset --all-targets --examples --bins --tests --target ${{ matrix.target }} + - name: Check build + run: cargo hack check -Z build-std=std,panic_abort --feature-powerset --target ${{ matrix.target }} + - name: Check docs + run: RUSTDOCFLAGS="-D warnings --cfg docsrs" cargo doc -Z build-std=std,panic_abort --no-deps --all-features --target ${{ matrix.target }} Clippy: name: Clippy runs-on: ubuntu-latest @@ -88,31 +116,3 @@ jobs: - uses: dtolnay/rust-toolchain@stable - name: Run Clippy run: cargo clippy --all-targets --all-features -- -D warnings - Docs: - name: Docs - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - target: ["aarch64-apple-ios", "aarch64-linux-android", "x86_64-apple-darwin", "x86_64-unknown-fuchsia", "x86_64-pc-windows-msvc", "x86_64-pc-solaris", "x86_64-unknown-freebsd", "x86_64-unknown-illumos", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl", "x86_64-unknown-netbsd", "x86_64-unknown-redox", "armv7-linux-androideabi", "i686-linux-android"] - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly # NOTE: need nightly for `doc_cfg` feature. - with: - targets: ${{ matrix.target }} - - name: Check docs for docs.rs - run: RUSTDOCFLAGS="-D warnings --cfg docsrs" cargo doc --no-deps --all-features --target ${{ matrix.target }} - DocsTier3: - name: Docs - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - target: ["armv7-sony-vita-newlibeabihf", "i686-unknown-hurd-gnu"] - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly # NOTE: need nightly for `doc_cfg` feature. - with: - components: "rust-src" - - name: Check docs for docs.rs - run: RUSTDOCFLAGS="-D warnings --cfg docsrs" cargo doc -Z build-std=std,panic_abort --no-deps --all-features --target ${{ matrix.target }} From 8e331cbc9c165760878fb6ad8501da895bbbc560 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Wed, 19 Jun 2024 09:23:50 +0200 Subject: [PATCH 11/33] Remove some unsuported targets Currently don't compile, might be worth adding at some point. --- .github/workflows/main.yml | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6ff17f92..26a531c7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -60,15 +60,12 @@ jobs: - aarch64-apple-darwin - aarch64-apple-ios - aarch64-apple-tvos - - aarch64-apple-visionos - aarch64-apple-watchos - aarch64-linux-android - aarch64-unknown-freebsd - - aarch64-unknown-hermit - aarch64-unknown-linux-gnu - aarch64-unknown-linux-musl - aarch64-unknown-netbsd - - aarch64-unknown-nto-qnx710 - aarch64-unknown-openbsd - aarch64-unknown-redox - arm-linux-androideabi @@ -78,20 +75,19 @@ jobs: - i686-linux-android - i686-unknown-hurd-gnu - i686-unknown-linux-gnu - - riscv32imc-esp-espidf - sparcv9-sun-solaris - - wasm32-wasi - x86_64-apple-darwin - x86_64-apple-ios - - x86_64-pc-nto-qnx710 - x86_64-pc-solaris - - x86_64-pc-windows-gnu + # Fails with: + # `rror calling dlltool 'x86_64-w64-mingw32-dlltool': No such file or + # directory (os error 2)`, build log: + # . + #- x86_64-pc-windows-gnu - x86_64-pc-windows-msvc - x86_64-unknown-dragonfly - x86_64-unknown-freebsd - x86_64-unknown-fuchsia - - x86_64-unknown-haiku - - x86_64-unknown-hermit - x86_64-unknown-illumos - x86_64-unknown-linux-gnu - x86_64-unknown-linux-musl From 7fa106c838d57ca62eb1564fa90f4678f6b92375 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Wed, 19 Jun 2024 09:28:42 +0200 Subject: [PATCH 12/33] Update to FreeBSD 14.1 on CI --- .cirrus.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cirrus.yml b/.cirrus.yml index 0cbae5f0..bbcb5413 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,5 +1,5 @@ freebsd_instance: - image_family: freebsd-13-2 + image: freebsd-14-1-release-amd64 env: RUST_BACKTRACE: full From 8c97337aadb726f7b6f3a1a3f90e969abb3a9732 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Wed, 19 Jun 2024 09:45:01 +0200 Subject: [PATCH 13/33] Use FreeBSD 13.2 again --- .cirrus.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index bbcb5413..dc68cea5 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,5 +1,5 @@ freebsd_instance: - image: freebsd-14-1-release-amd64 + image: freebsd-13-2-release-amd64 env: RUST_BACKTRACE: full @@ -7,7 +7,7 @@ env: task: name: FreeBSD setup_script: - - curl https://sh.rustup.rs -sSf --output rustup.sh + - fetch https://sh.rustup.rs -o rustup.sh - sh rustup.sh -y --profile minimal cargo_cache: folder: $HOME/.cargo/registry From 3a938932829ea6ee3025d2d7a86c7b095c76e6c3 Mon Sep 17 00:00:00 2001 From: Quentin Perez Date: Tue, 2 Jul 2024 10:52:17 +0200 Subject: [PATCH 14/33] Add Apple visionOS support --- .github/workflows/main.yml | 1 + src/lib.rs | 4 ++++ src/sockaddr.rs | 3 +++ src/socket.rs | 5 +++++ src/sys/unix.rs | 34 ++++++++++++++++++++++++++++++++++ tests/socket.rs | 13 +++++++++++++ 6 files changed, 60 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 26a531c7..3a1b10f4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -60,6 +60,7 @@ jobs: - aarch64-apple-darwin - aarch64-apple-ios - aarch64-apple-tvos + - aarch64-apple-visionos - aarch64-apple-watchos - aarch64-linux-android - aarch64-unknown-freebsd diff --git a/src/lib.rs b/src/lib.rs index c3161d63..8f593163 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -515,6 +515,7 @@ impl TcpKeepalive { target_os = "fuchsia", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -531,6 +532,7 @@ impl TcpKeepalive { target_os = "fuchsia", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -559,6 +561,7 @@ impl TcpKeepalive { target_os = "fuchsia", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -577,6 +580,7 @@ impl TcpKeepalive { target_os = "fuchsia", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", diff --git a/src/sockaddr.rs b/src/sockaddr.rs index 2f4b40ed..c80dccf3 100644 --- a/src/sockaddr.rs +++ b/src/sockaddr.rs @@ -291,6 +291,7 @@ impl From for SockAddr { target_os = "haiku", target_os = "hermit", target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "netbsd", target_os = "nto", @@ -334,6 +335,7 @@ impl From for SockAddr { target_os = "haiku", target_os = "hermit", target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "netbsd", target_os = "nto", @@ -358,6 +360,7 @@ impl fmt::Debug for SockAddr { target_os = "haiku", target_os = "hermit", target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "netbsd", target_os = "nto", diff --git a/src/socket.rs b/src/socket.rs index e0ccf8e4..8d517b47 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -801,6 +801,7 @@ fn set_common_flags(socket: Socket) -> io::Result { // On Apple platforms set `NOSIGPIPE`. #[cfg(any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -2048,6 +2049,7 @@ impl Socket { target_os = "fuchsia", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -2066,6 +2068,7 @@ impl Socket { target_os = "fuchsia", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -2095,6 +2098,7 @@ impl Socket { target_os = "fuchsia", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -2113,6 +2117,7 @@ impl Socket { target_os = "fuchsia", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 51ef4a5d..3a898bc3 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -18,6 +18,7 @@ use std::net::{Ipv4Addr, Ipv6Addr}; feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -31,6 +32,7 @@ use std::num::NonZeroU32; target_os = "android", target_os = "freebsd", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "tvos", @@ -46,6 +48,7 @@ use std::os::unix::ffi::OsStrExt; target_os = "android", target_os = "freebsd", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "tvos", @@ -63,6 +66,7 @@ use std::{io, slice}; #[cfg(not(any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -160,6 +164,7 @@ pub(crate) use libc::IP_RECVTOS; pub(crate) use libc::IP_TOS; #[cfg(not(any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -167,6 +172,7 @@ pub(crate) use libc::IP_TOS; pub(crate) use libc::SO_LINGER; #[cfg(any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -202,6 +208,7 @@ pub(crate) use libc::{ target_os = "haiku", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "netbsd", target_os = "nto", @@ -217,6 +224,7 @@ pub(crate) use libc::{IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP}; target_os = "haiku", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "netbsd", target_os = "openbsd", @@ -236,6 +244,7 @@ pub(crate) use libc::{ target_os = "fuchsia", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -250,6 +259,7 @@ pub(crate) type Bool = c_int; #[cfg(any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "nto", target_os = "tvos", @@ -259,6 +269,7 @@ use libc::TCP_KEEPALIVE as KEEPALIVE_TIME; #[cfg(not(any( target_os = "haiku", target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "nto", target_os = "openbsd", @@ -284,6 +295,7 @@ macro_rules! syscall { /// Maximum size of a buffer passed to system call like `recv` and `send`. #[cfg(not(any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -300,6 +312,7 @@ const MAX_BUF_LEN: usize = ssize_t::MAX as usize; // both platforms. #[cfg(any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -339,6 +352,7 @@ type IovLen = usize; target_os = "hurd", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "netbsd", target_os = "nto", @@ -1234,6 +1248,7 @@ pub(crate) fn set_tcp_keepalive(fd: Socket, keepalive: &TcpKeepalive) -> io::Res target_os = "hurd", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -1462,6 +1477,7 @@ impl crate::Socket { #[cfg_attr( any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos" @@ -1498,6 +1514,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -1509,6 +1526,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -1521,6 +1539,7 @@ impl crate::Socket { #[cfg(any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -1957,6 +1976,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -1968,6 +1988,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -1993,6 +2014,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -2004,6 +2026,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -2029,6 +2052,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -2040,6 +2064,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -2060,6 +2085,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -2071,6 +2097,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -2088,6 +2115,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -2099,6 +2127,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -2119,6 +2148,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -2130,6 +2160,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -2453,6 +2484,7 @@ impl crate::Socket { target_os = "android", target_os = "freebsd", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "tvos", @@ -2468,6 +2500,7 @@ impl crate::Socket { target_os = "android", target_os = "freebsd", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "tvos", @@ -2491,6 +2524,7 @@ impl crate::Socket { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", diff --git a/tests/socket.rs b/tests/socket.rs index 8e22542d..2300f0ed 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -5,6 +5,7 @@ target_os = "android", target_os = "freebsd", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "tvos", @@ -29,6 +30,7 @@ use std::net::{Ipv6Addr, SocketAddrV6}; target_os = "android", target_os = "freebsd", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "tvos", @@ -225,6 +227,7 @@ fn assert_common_flags(socket: &Socket, expected: bool) { assert_close_on_exec(socket, expected); #[cfg(any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -416,6 +419,7 @@ where feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -436,6 +440,7 @@ fn set_nosigpipe() { /// Assert that `SO_NOSIGPIPE` is set on `socket`. #[cfg(any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -864,6 +869,7 @@ fn tcp_keepalive() { target_os = "freebsd", target_os = "fuchsia", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -881,6 +887,7 @@ fn tcp_keepalive() { target_os = "freebsd", target_os = "fuchsia", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -908,6 +915,7 @@ fn tcp_keepalive() { target_os = "fuchsia", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -929,6 +937,7 @@ fn tcp_keepalive() { target_os = "fuchsia", target_os = "illumos", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "netbsd", @@ -977,6 +986,7 @@ fn device() { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -1022,6 +1032,7 @@ fn device() { feature = "all", any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", @@ -1069,6 +1080,7 @@ fn device_v6() { target_os = "android", target_os = "freebsd", target_os = "ios", + target_os = "visionos", target_os = "linux", target_os = "macos", target_os = "tvos", @@ -1226,6 +1238,7 @@ fn r#type() { unix, not(any( target_os = "ios", + target_os = "visionos", target_os = "macos", target_os = "tvos", target_os = "watchos", From 68de29bc98eb2effd38c977e160417c0a7e99f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Nicola?= Date: Thu, 21 Nov 2024 13:23:28 +0100 Subject: [PATCH 15/33] Remove Socket::(set_)header_included_v6 on unsupported OS --- src/socket.rs | 24 ++++++++++++++++++++++-- tests/socket.rs | 12 +++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/socket.rs b/src/socket.rs index 8d517b47..3d9d44af 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1682,7 +1682,17 @@ impl Socket { /// For more information about this option, see [`set_header_included`]. /// /// [`set_header_included`]: Socket::set_header_included - #[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))] + #[cfg(all( + feature = "all", + not(any( + target_os = "redox", + target_os = "espidf", + target_os = "openbsd", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "netbsd" + )) + ))] #[cfg_attr( docsrs, doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) @@ -1706,7 +1716,17 @@ impl Socket { any(target_os = "fuchsia", target_os = "illumos", target_os = "solaris"), allow(rustdoc::broken_intra_doc_links) )] - #[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))] + #[cfg(all( + feature = "all", + not(any( + target_os = "redox", + target_os = "espidf", + target_os = "openbsd", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "netbsd" + )) + ))] #[cfg_attr( docsrs, doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) diff --git a/tests/socket.rs b/tests/socket.rs index 2300f0ed..c87ca0e0 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1564,7 +1564,17 @@ fn header_included() { } #[test] -#[cfg(all(feature = "all", not(target_os = "redox")))] +#[cfg(all( + feature = "all", + not(any( + target_os = "redox", + target_os = "espidf", + target_os = "openbsd", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "netbsd" + )) +))] fn header_included_ipv6() { let socket = match Socket::new(Domain::IPV6, Type::RAW, None) { Ok(socket) => socket, From 33a98be5635c816a18b490f6d3888b667639c891 Mon Sep 17 00:00:00 2001 From: Keith Mattix II Date: Wed, 27 Nov 2024 10:12:04 -0600 Subject: [PATCH 16/33] Add support for original_dst for windows (#529) --- src/socket.rs | 42 ++++++++++++++++++++ src/sys/unix.rs | 97 ++++++++++++++++++++-------------------------- src/sys/windows.rs | 46 +++++++++++++++++++++- tests/socket.rs | 33 +++++++++++++--- 4 files changed, 154 insertions(+), 64 deletions(-) diff --git a/src/socket.rs b/src/socket.rs index 3d9d44af..4e41793c 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -2225,6 +2225,48 @@ impl Socket { ) } } + + /// Get the value for the `SO_ORIGINAL_DST` option on this socket. + #[cfg(all( + feature = "all", + any( + target_os = "android", + target_os = "fuchsia", + target_os = "linux", + target_os = "windows", + ) + ))] + #[cfg_attr( + docsrs, + doc(cfg(all( + feature = "all", + any( + target_os = "android", + target_os = "fuchsia", + target_os = "linux", + target_os = "windows", + ) + ))) + )] + pub fn original_dst(&self) -> io::Result { + sys::original_dst(self.as_raw()) + } + + /// Get the value for the `IP6T_SO_ORIGINAL_DST` option on this socket. + #[cfg(all( + feature = "all", + any(target_os = "android", target_os = "linux", target_os = "windows") + ))] + #[cfg_attr( + docsrs, + doc(cfg(all( + feature = "all", + any(target_os = "android", target_os = "linux", target_os = "windows") + ))) + )] + pub fn original_dst_ipv6(&self) -> io::Result { + sys::original_dst_ipv6(self.as_raw()) + } } impl Read for Socket { diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 3a898bc3..1451b1f4 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -1406,6 +1406,47 @@ pub(crate) const fn to_mreqn( } } +#[cfg(all( + feature = "all", + any(target_os = "android", target_os = "fuchsia", target_os = "linux") +))] +pub(crate) fn original_dst(fd: Socket) -> io::Result { + // Safety: `getsockopt` initialises the `SockAddr` for us. + unsafe { + SockAddr::try_init(|storage, len| { + syscall!(getsockopt( + fd, + libc::SOL_IP, + libc::SO_ORIGINAL_DST, + storage.cast(), + len + )) + }) + } + .map(|(_, addr)| addr) +} + +/// Get the value for the `IP6T_SO_ORIGINAL_DST` option on this socket. +/// +/// This value contains the original destination IPv6 address of the connection +/// redirected using `ip6tables` `REDIRECT` or `TPROXY`. +#[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] +pub(crate) fn original_dst_ipv6(fd: Socket) -> io::Result { + // Safety: `getsockopt` initialises the `SockAddr` for us. + unsafe { + SockAddr::try_init(|storage, len| { + syscall!(getsockopt( + fd, + libc::SOL_IPV6, + libc::IP6T_SO_ORIGINAL_DST, + storage.cast(), + len + )) + }) + } + .map(|(_, addr)| addr) +} + /// Unix only API. impl crate::Socket { /// Accept a new incoming connection from this listener. @@ -2402,62 +2443,6 @@ impl crate::Socket { } } - /// Get the value for the `SO_ORIGINAL_DST` option on this socket. - /// - /// This value contains the original destination IPv4 address of the connection - /// redirected using `iptables` `REDIRECT` or `TPROXY`. - #[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 original_dst(&self) -> io::Result { - // Safety: `getsockopt` initialises the `SockAddr` for us. - unsafe { - SockAddr::try_init(|storage, len| { - syscall!(getsockopt( - self.as_raw(), - libc::SOL_IP, - libc::SO_ORIGINAL_DST, - storage.cast(), - len - )) - }) - } - .map(|(_, addr)| addr) - } - - /// Get the value for the `IP6T_SO_ORIGINAL_DST` option on this socket. - /// - /// This value contains the original destination IPv6 address of the connection - /// redirected using `ip6tables` `REDIRECT` or `TPROXY`. - #[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 original_dst_ipv6(&self) -> io::Result { - // Safety: `getsockopt` initialises the `SockAddr` for us. - unsafe { - SockAddr::try_init(|storage, len| { - syscall!(getsockopt( - self.as_raw(), - libc::SOL_IPV6, - libc::IP6T_SO_ORIGINAL_DST, - storage.cast(), - len - )) - }) - } - .map(|(_, addr)| addr) - } - /// Copies data between a `file` and this socket using the `sendfile(2)` /// system call. Because this copying is done within the kernel, /// `sendfile()` is more efficient than the combination of `read(2)` and diff --git a/src/sys/windows.rs b/src/sys/windows.rs index 11f2b7b0..8cf27b53 100644 --- a/src/sys/windows.rs +++ b/src/sys/windows.rs @@ -20,14 +20,16 @@ use std::time::{Duration, Instant}; use std::{process, ptr, slice}; use windows_sys::Win32::Foundation::{SetHandleInformation, HANDLE, HANDLE_FLAG_INHERIT}; -#[cfg(feature = "all")] -use windows_sys::Win32::Networking::WinSock::SO_PROTOCOL_INFOW; use windows_sys::Win32::Networking::WinSock::{ self, tcp_keepalive, FIONBIO, IN6_ADDR, IN6_ADDR_0, INVALID_SOCKET, IN_ADDR, IN_ADDR_0, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, SD_BOTH, SD_RECEIVE, SD_SEND, SIO_KEEPALIVE_VALS, SOCKET_ERROR, WSABUF, WSAEMSGSIZE, WSAESHUTDOWN, WSAPOLLFD, WSAPROTOCOL_INFOW, WSA_FLAG_NO_HANDLE_INHERIT, WSA_FLAG_OVERLAPPED, }; +#[cfg(feature = "all")] +use windows_sys::Win32::Networking::WinSock::{ + IP6T_SO_ORIGINAL_DST, SOL_IP, SO_ORIGINAL_DST, SO_PROTOCOL_INFOW, +}; use windows_sys::Win32::System::Threading::INFINITE; use crate::{MsgHdr, RecvFlags, SockAddr, TcpKeepalive, Type}; @@ -857,6 +859,46 @@ pub(crate) fn to_mreqn( } } +#[cfg(feature = "all")] +pub(crate) fn original_dst(socket: Socket) -> io::Result { + unsafe { + SockAddr::try_init(|storage, len| { + syscall!( + getsockopt( + socket, + SOL_IP as i32, + SO_ORIGINAL_DST as i32, + storage.cast(), + len, + ), + PartialEq::eq, + SOCKET_ERROR + ) + }) + } + .map(|(_, addr)| addr) +} + +#[cfg(feature = "all")] +pub(crate) fn original_dst_ipv6(socket: Socket) -> io::Result { + unsafe { + SockAddr::try_init(|storage, len| { + syscall!( + getsockopt( + socket, + SOL_IP as i32, + IP6T_SO_ORIGINAL_DST as i32, + storage.cast(), + len, + ), + PartialEq::eq, + SOCKET_ERROR + ) + }) + } + .map(|(_, addr)| addr) +} + #[allow(unsafe_op_in_unsafe_fn)] pub(crate) fn unix_sockaddr(path: &Path) -> io::Result { // SAFETY: a `sockaddr_storage` of all zeros is valid. diff --git a/tests/socket.rs b/tests/socket.rs index c87ca0e0..0959ef39 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1600,36 +1600,57 @@ fn header_included_ipv6() { #[test] #[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 = "windows" + ) ))] fn original_dst() { let socket = Socket::new(Domain::IPV4, Type::STREAM, None).unwrap(); + #[cfg(not(target_os = "windows"))] + let expected = Some(libc::ENOENT); + #[cfg(target_os = "windows")] + let expected = Some(windows_sys::Win32::Networking::WinSock::WSAEINVAL); + match socket.original_dst() { Ok(_) => panic!("original_dst on non-redirected socket should fail"), - Err(err) => assert_eq!(err.raw_os_error(), Some(libc::ENOENT)), + Err(err) => assert_eq!(err.raw_os_error(), expected), } let socket = Socket::new(Domain::IPV6, Type::STREAM, None).unwrap(); match socket.original_dst() { Ok(_) => panic!("original_dst on non-redirected socket should fail"), - Err(err) => assert_eq!(err.raw_os_error(), Some(libc::ENOENT)), + Err(err) => assert_eq!(err.raw_os_error(), expected), } } #[test] -#[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] +#[cfg(all( + feature = "all", + any(target_os = "android", target_os = "fuchsia", target_os = "linux") +))] fn original_dst_ipv6() { let socket = Socket::new(Domain::IPV6, Type::STREAM, None).unwrap(); + #[cfg(not(target_os = "windows"))] + let expected = Some(libc::ENOENT); + #[cfg(target_os = "windows")] + let expected = Some(windows_sys::Win32::Networking::WinSock::WSAEINVAL); + #[cfg(not(target_os = "windows"))] + let expected_v4 = Some(libc::EOPNOTSUPP); + #[cfg(target_os = "windows")] + let expected_v4 = Some(windows_sys::Win32::Networking::WinSock::WSAEINVAL); match socket.original_dst_ipv6() { Ok(_) => panic!("original_dst_ipv6 on non-redirected socket should fail"), - Err(err) => assert_eq!(err.raw_os_error(), Some(libc::ENOENT)), + Err(err) => assert_eq!(err.raw_os_error(), expected), } // Not supported on IPv4 socket. let socket = Socket::new(Domain::IPV4, Type::STREAM, None).unwrap(); match socket.original_dst_ipv6() { Ok(_) => panic!("original_dst_ipv6 on non-redirected socket should fail"), - Err(err) => assert_eq!(err.raw_os_error(), Some(libc::EOPNOTSUPP)), + Err(err) => assert_eq!(err.raw_os_error(), expected_v4), } } From 60d118fa4724f756c31944c86dc1ecd5dfc4c9b7 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Thu, 28 Nov 2024 11:03:56 +0100 Subject: [PATCH 17/33] Release v0.5.8 (#537) --- .github/workflows/main.yml | 6 ++++-- CHANGELOG.md | 9 +++++++++ Cargo.toml | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3a1b10f4..7a5126d2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -60,7 +60,8 @@ jobs: - aarch64-apple-darwin - aarch64-apple-ios - aarch64-apple-tvos - - aarch64-apple-visionos + # Broken, see https://github.com/rust-lang/socket2/issues/538. + #- aarch64-apple-visionos - aarch64-apple-watchos - aarch64-linux-android - aarch64-unknown-freebsd @@ -74,7 +75,8 @@ jobs: - armv7-linux-androideabi - armv7-sony-vita-newlibeabihf - i686-linux-android - - i686-unknown-hurd-gnu + # Broken, see https://github.com/rust-lang/socket2/issues/539. + #- i686-unknown-hurd-gnu - i686-unknown-linux-gnu - sparcv9-sun-solaris - x86_64-apple-darwin diff --git a/CHANGELOG.md b/CHANGELOG.md index b90e67c2..f416f22c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# 0.5.8 + +* Added `Socket::(set_)header_included_v4` and + `Socket::(set_)header_included_v6` + (https://github.com/rust-lang/socket2/pull/518). +* Added support for `Socket::original_dst` and + `Socket::original_dst_ipv6` on Windows + (https://github.com/rust-lang/socket2/pull/529). + # 0.5.7 * Added `Socket::(set_)passcred` diff --git a/Cargo.toml b/Cargo.toml index 8ef85ebc..fbb7fea9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "socket2" -version = "0.5.7" +version = "0.5.8" authors = [ "Alex Crichton ", "Thomas de Zeeuw " From 56e625efa4c85157636027823af1b1cc84e758f6 Mon Sep 17 00:00:00 2001 From: andreybuchinskiy Date: Thu, 5 Dec 2024 02:26:54 -0700 Subject: [PATCH 18/33] Add Socket::(set_)recv_hoplimit_v6 (#543) --- src/socket.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ src/sys/unix.rs | 17 ++++++++++++++ tests/socket.rs | 18 +++++++++++++++ 3 files changed, 96 insertions(+) diff --git a/src/socket.rs b/src/socket.rs index 4e41793c..698d3556 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -2018,6 +2018,67 @@ impl Socket { ) } } + + /// Get the value of the `IPV6_RECVHOPLIMIT` option for this socket. + /// + /// For more information about this option, see [`set_recv_hoplimit_v6`]. + /// + /// [`set_recv_hoplimit_v6`]: Socket::set_recv_hoplimit_v6 + #[cfg(all( + feature = "all", + not(any( + windows, + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + target_os = "haiku", + target_os = "hurd", + target_os = "espidf", + target_os = "vita", + )) + ))] + pub fn recv_hoplimit_v6(&self) -> io::Result { + unsafe { + getsockopt::(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_RECVHOPLIMIT) + .map(|recv_hoplimit| recv_hoplimit > 0) + } + } + /// Set the value of the `IPV6_RECVHOPLIMIT` option for this socket. + /// + /// The received hop limit is returned as ancillary data by recvmsg() + /// only if the application has enabled the IPV6_RECVHOPLIMIT socket + /// option: + #[cfg(all( + feature = "all", + not(any( + windows, + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + target_os = "haiku", + target_os = "hurd", + target_os = "espidf", + target_os = "vita", + )) + ))] + pub fn set_recv_hoplimit_v6(&self, recv_hoplimit: bool) -> io::Result<()> { + unsafe { + setsockopt( + self.as_raw(), + sys::IPPROTO_IPV6, + sys::IPV6_RECVHOPLIMIT, + recv_hoplimit as c_int, + ) + } + } } /// Socket options for TCP sockets, get/set using `IPPROTO_TCP`. diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 1451b1f4..b40c3df1 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -122,6 +122,23 @@ pub(crate) use libc::SO_OOBINLINE; // Used in `Socket`. #[cfg(not(target_os = "nto"))] pub(crate) use libc::ipv6_mreq as Ipv6Mreq; +#[cfg(all( + feature = "all", + not(any( + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "hurd", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + target_os = "haiku", + target_os = "espidf", + target_os = "vita", + )) +))] +pub(crate) use libc::IPV6_RECVHOPLIMIT; #[cfg(not(any( target_os = "dragonfly", target_os = "fuchsia", diff --git a/tests/socket.rs b/tests/socket.rs index 0959ef39..98a535c7 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1475,6 +1475,24 @@ test!(IPv6 tclass_v6, set_tclass_v6(96)); )))] test!(IPv6 recv_tclass_v6, set_recv_tclass_v6(true)); +#[cfg(all( + feature = "all", + not(any( + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "hurd", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + target_os = "windows", + target_os = "vita", + target_os = "haiku", + )) +))] +test!(IPv6 recv_hoplimit_v6, set_recv_hoplimit_v6(true)); + #[cfg(all( feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") From 0cb51192f91f63c31373b8bd6cd8aeeddcbc610c Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sat, 25 Jan 2025 10:53:59 +0100 Subject: [PATCH 19/33] Start v0.6 development --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index fbb7fea9..c8656f05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "socket2" -version = "0.5.8" +version = "0.6.0" +publish = false # In development. authors = [ "Alex Crichton ", "Thomas de Zeeuw " From f0ed4388c088a2df648355b1711682078b834d09 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Mon, 27 Jan 2025 16:33:49 +0100 Subject: [PATCH 20/33] Remove Socket::(bind_)device_by_index (#548) Replaced by Socket::(bind_)device_by_index_v4. --- src/sys/unix.rs | 58 ------------------------------------------------- 1 file changed, 58 deletions(-) diff --git a/src/sys/unix.rs b/src/sys/unix.rs index b40c3df1..05cb2e91 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -2029,35 +2029,6 @@ impl crate::Socket { .map(|_| ()) } - /// This method is deprecated, use [`crate::Socket::bind_device_by_index_v4`]. - #[cfg(all( - feature = "all", - any( - target_os = "ios", - target_os = "visionos", - target_os = "macos", - target_os = "tvos", - target_os = "watchos", - ) - ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "ios", - target_os = "visionos", - target_os = "macos", - target_os = "tvos", - target_os = "watchos", - ) - ))) - )] - #[deprecated = "Use `Socket::bind_device_by_index_v4` instead"] - pub fn bind_device_by_index(&self, interface: Option) -> io::Result<()> { - self.bind_device_by_index_v4(interface) - } - /// Sets the value for `IP_BOUND_IF` option on this socket. /// /// If a socket is bound to an interface, only packets received from that @@ -2168,35 +2139,6 @@ impl crate::Socket { Ok(NonZeroU32::new(index)) } - /// This method is deprecated, use [`crate::Socket::device_index_v4`]. - #[cfg(all( - feature = "all", - any( - target_os = "ios", - target_os = "visionos", - target_os = "macos", - target_os = "tvos", - target_os = "watchos", - ) - ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "ios", - target_os = "visionos", - target_os = "macos", - target_os = "tvos", - target_os = "watchos", - ) - ))) - )] - #[deprecated = "Use `Socket::device_index_v4` instead"] - pub fn device_index(&self) -> io::Result> { - self.device_index_v4() - } - /// Gets the value for `IPV6_BOUND_IF` option on this socket, i.e. the index /// for the interface to which the socket is bound. /// From 25337f182c3902250548c04f8d22c38d41a9d796 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Mon, 27 Jan 2025 16:34:07 +0100 Subject: [PATCH 21/33] Remove Socket::(set_)header_included (#547) Replaced by Socket::(set_)header_included_v4. --- src/socket.rs | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/src/socket.rs b/src/socket.rs index 698d3556..66b8420d 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1139,21 +1139,11 @@ const fn into_linger(duration: Option) -> sys::linger { /// * Linux: /// * Windows: impl Socket { - /// This method is deprecated, use [`crate::Socket::header_included_v4`]. - #[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))] - #[cfg_attr( - docsrs, - doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) - )] - #[deprecated = "Use `Socket::header_included_v4` instead"] - pub fn header_included(&self) -> io::Result { - self.header_included_v4() - } /// Get the value of the `IP_HDRINCL` option on this socket. /// - /// For more information about this option, see [`set_header_included`]. + /// For more information about this option, see [`set_header_included_v4`]. /// - /// [`set_header_included`]: Socket::set_header_included + /// [`set_header_included_v4`]: Socket::set_header_included_v4 #[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))] #[cfg_attr( docsrs, @@ -1166,21 +1156,6 @@ impl Socket { } } - /// This method is deprecated, use [`crate::Socket::set_header_included_v4`]. - #[cfg_attr( - any(target_os = "fuchsia", target_os = "illumos", target_os = "solaris"), - allow(rustdoc::broken_intra_doc_links) - )] - #[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))] - #[cfg_attr( - docsrs, - doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) - )] - #[deprecated = "Use `Socket::set_header_included_v4` instead"] - pub fn set_header_included(&self, included: bool) -> io::Result<()> { - self.set_header_included_v4(included) - } - /// Set the value of the `IP_HDRINCL` option on this socket. /// /// If enabled, the user supplies an IP header in front of the user data. @@ -1679,9 +1654,9 @@ impl Socket { impl Socket { /// Get the value of the `IP_HDRINCL` option on this socket. /// - /// For more information about this option, see [`set_header_included`]. + /// For more information about this option, see [`set_header_included_v6`]. /// - /// [`set_header_included`]: Socket::set_header_included + /// [`set_header_included_v6`]: Socket::set_header_included_v6 #[cfg(all( feature = "all", not(any( From a38d197160dca1085051278bf6da52485306f70a Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sat, 25 Jan 2025 11:14:50 +0100 Subject: [PATCH 22/33] Suffix Socket::(set_)ttl with v4 To indicate it an option for IPv4 sockets. --- src/socket.rs | 10 +++++----- tests/socket.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/socket.rs b/src/socket.rs index 66b8420d..06bc7209 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1165,8 +1165,8 @@ impl Socket { /// /// [`SOCK_RAW`]: Type::RAW /// [raw(7)]: https://man7.org/linux/man-pages/man7/raw.7.html - /// [`IP_TTL`]: Socket::set_ttl /// [`IP_TOS`]: Socket::set_tos + /// [`IP_TTL`]: Socket::set_ttl_v4 #[cfg_attr( any(target_os = "fuchsia", target_os = "illumos", target_os = "solaris"), allow(rustdoc::broken_intra_doc_links) @@ -1531,10 +1531,10 @@ impl Socket { /// Get the value of the `IP_TTL` option for this socket. /// - /// For more information about this option, see [`set_ttl`]. + /// For more information about this option, see [`set_ttl_v4`]. /// - /// [`set_ttl`]: Socket::set_ttl - pub fn ttl(&self) -> io::Result { + /// [`set_ttl_v4`]: Socket::set_ttl_v4 + pub fn ttl_v4(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_IP, sys::IP_TTL).map(|ttl| ttl as u32) } @@ -1544,7 +1544,7 @@ impl Socket { /// /// This value sets the time-to-live field that is used in every packet sent /// from this socket. - pub fn set_ttl(&self, ttl: u32) -> io::Result<()> { + pub fn set_ttl_v4(&self, ttl: u32) -> io::Result<()> { unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_TTL, ttl as c_int) } } diff --git a/tests/socket.rs b/tests/socket.rs index 98a535c7..e79a5a1a 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1401,7 +1401,7 @@ test!(freebind, set_freebind(true)); #[cfg(all(feature = "all", target_os = "linux"))] test!(IPv6 freebind_ipv6, set_freebind_ipv6(true)); -test!(IPv4 ttl, set_ttl(40)); +test!(IPv4 ttl_v4, set_ttl_v4(40)); #[cfg(not(any( target_os = "fuchsia", From 0e3f43693db6055b83f31ba4f3d00df973fa71fd Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sat, 25 Jan 2025 11:15:48 +0100 Subject: [PATCH 23/33] Suffix Socket::(set_)tos with v4 To indicate it an option for IPv4 sockets. --- src/socket.rs | 10 +++++----- tests/socket.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/socket.rs b/src/socket.rs index 06bc7209..f95d15f6 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1165,8 +1165,8 @@ impl Socket { /// /// [`SOCK_RAW`]: Type::RAW /// [raw(7)]: https://man7.org/linux/man-pages/man7/raw.7.html - /// [`IP_TOS`]: Socket::set_tos /// [`IP_TTL`]: Socket::set_ttl_v4 + /// [`IP_TOS`]: Socket::set_tos_v4 #[cfg_attr( any(target_os = "fuchsia", target_os = "illumos", target_os = "solaris"), allow(rustdoc::broken_intra_doc_links) @@ -1562,18 +1562,18 @@ impl Socket { target_os = "illumos", target_os = "haiku", )))] - pub fn set_tos(&self, tos: u32) -> io::Result<()> { + pub fn set_tos_v4(&self, tos: u32) -> io::Result<()> { unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_TOS, tos as c_int) } } /// Get the value of the `IP_TOS` option for this socket. /// - /// For more information about this option, see [`set_tos`]. + /// For more information about this option, see [`set_tos_v4`]. /// /// NOTE: /// documents that not all versions of windows support `IP_TOS`. /// - /// [`set_tos`]: Socket::set_tos + /// [`set_tos_v4`]: Socket::set_tos_v4 #[cfg(not(any( target_os = "fuchsia", target_os = "redox", @@ -1581,7 +1581,7 @@ impl Socket { target_os = "illumos", target_os = "haiku", )))] - pub fn tos(&self) -> io::Result { + pub fn tos_v4(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_IP, sys::IP_TOS).map(|tos| tos as u32) } diff --git a/tests/socket.rs b/tests/socket.rs index e79a5a1a..28f1e84f 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1410,7 +1410,7 @@ test!(IPv4 ttl_v4, set_ttl_v4(40)); target_os = "illumos", target_os = "haiku", )))] -test!(IPv4 tos, set_tos(96)); +test!(IPv4 tos_v4, set_tos_v4(96)); #[cfg(not(any( target_os = "dragonfly", From 11428df0c8908daafd2faafa56ddfeddecd2de38 Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sat, 25 Jan 2025 11:16:09 +0100 Subject: [PATCH 24/33] Suffix Socket::(set_)ip_transparent with v4 To indicate it an option for IPv4 sockets. --- src/socket.rs | 8 ++++---- tests/socket.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/socket.rs b/src/socket.rs index f95d15f6..2095cb34 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1189,12 +1189,12 @@ impl Socket { /// 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`]: Socket::set_ip_transparent_v4 #[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 { + pub fn ip_transparent_v4(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_IP, libc::IP_TRANSPARENT) .map(|transparent| transparent != 0) @@ -1218,7 +1218,7 @@ impl Socket { /// 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<()> { + 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 28f1e84f..c1a407da 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1366,8 +1366,8 @@ test!( #[cfg(all(feature = "all", target_os = "linux"))] 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 171d1eb57a9b71956971fbcb0949a6b8dee55e2f Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sat, 25 Jan 2025 11:16:27 +0100 Subject: [PATCH 25/33] Suffix Socket::(set_)recv_tos with v4 To indicate it an option for IPv4 sockets. --- src/socket.rs | 8 ++++---- tests/socket.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/socket.rs b/src/socket.rs index 2095cb34..e6cdca24 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1607,7 +1607,7 @@ impl Socket { target_os = "espidf", target_os = "vita", )))] - pub fn set_recv_tos(&self, recv_tos: bool) -> io::Result<()> { + pub fn set_recv_tos_v4(&self, recv_tos: bool) -> io::Result<()> { unsafe { setsockopt( self.as_raw(), @@ -1620,9 +1620,9 @@ impl Socket { /// Get the value of the `IP_RECVTOS` option for this socket. /// - /// For more information about this option, see [`set_recv_tos`]. + /// For more information about this option, see [`set_recv_tos_v4`]. /// - /// [`set_recv_tos`]: Socket::set_recv_tos + /// [`set_recv_tos_v4`]: Socket::set_recv_tos_v4 #[cfg(not(any( target_os = "aix", target_os = "dragonfly", @@ -1638,7 +1638,7 @@ impl Socket { target_os = "espidf", target_os = "vita", )))] - pub fn recv_tos(&self) -> io::Result { + pub fn recv_tos_v4(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_IP, sys::IP_RECVTOS) .map(|recv_tos| recv_tos > 0) diff --git a/tests/socket.rs b/tests/socket.rs index c1a407da..3776a4b4 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1425,7 +1425,7 @@ test!(IPv4 tos_v4, set_tos_v4(96)); target_os = "vita", target_os = "haiku", )))] -test!(IPv4 recv_tos, set_recv_tos(true)); +test!(IPv4 recv_tos_v4, set_recv_tos_v4(true)); #[cfg(not(windows))] // TODO: returns `WSAENOPROTOOPT` (10042) on Windows. test!(IPv4 broadcast, set_broadcast(true)); From 0ae0c3a3e9e898677dc48eef88c74bf7fbd99a88 Mon Sep 17 00:00:00 2001 From: Geoffry Song Date: Sun, 26 Jan 2025 21:24:10 -0800 Subject: [PATCH 26/33] Fix docs link for AsFd --- src/sockref.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sockref.rs b/src/sockref.rs index d23b7c0f..94b84dd4 100644 --- a/src/sockref.rs +++ b/src/sockref.rs @@ -20,7 +20,7 @@ use crate::Socket; /// /// [`TcpStream`]: std::net::TcpStream // Don't use intra-doc links because they won't build on every platform. -/// [`AsFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.AsFd.html +/// [`AsFd`]: https://doc.rust-lang.org/stable/std/os/fd/trait.AsFd.html /// [`AsSocket`]: https://doc.rust-lang.org/stable/std/os/windows/io/trait.AsSocket.html /// /// # Examples From 23f7a86b486648aa709291288e3fe08feec53ac1 Mon Sep 17 00:00:00 2001 From: Nugine Date: Sun, 16 Feb 2025 19:21:42 +0800 Subject: [PATCH 27/33] Document support for OpenHarmony (#553) --- .github/workflows/main.yml | 3 +++ README.md | 1 + 2 files changed, 4 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7a5126d2..20ca0d1c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -67,6 +67,7 @@ jobs: - aarch64-unknown-freebsd - aarch64-unknown-linux-gnu - aarch64-unknown-linux-musl + - aarch64-unknown-linux-ohos - aarch64-unknown-netbsd - aarch64-unknown-openbsd - aarch64-unknown-redox @@ -74,6 +75,7 @@ jobs: - arm64_32-apple-watchos - armv7-linux-androideabi - armv7-sony-vita-newlibeabihf + - armv7-unknown-linux-ohos - i686-linux-android # Broken, see https://github.com/rust-lang/socket2/issues/539. #- i686-unknown-hurd-gnu @@ -94,6 +96,7 @@ jobs: - x86_64-unknown-illumos - x86_64-unknown-linux-gnu - x86_64-unknown-linux-musl + - x86_64-unknown-linux-ohos - x86_64-unknown-netbsd - x86_64-unknown-openbsd - x86_64-unknown-redox diff --git a/README.md b/README.md index 8bb09495..d84e40c5 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ feature flag. * NetBSD * Redox * Solaris +* OpenHarmony # Minimum Supported Rust Version (MSRV) From 62479f73a41063501ded9ef82ebb215ae1d3053a Mon Sep 17 00:00:00 2001 From: Pavel Roskin <1317472+proski@users.noreply.github.com> Date: Tue, 18 Feb 2025 01:07:47 -0800 Subject: [PATCH 28/33] Improve documentation generation (#554) Make `x86_64-unknown-linux-gnu` the default target, as it's more feature rich. Users may not realize that they can select their platform on docs.rs, so it's better to show them more extensive documentation. Don't pass `--cfg docsrs` to rustdoc for docs.rs builds, it's already passed by docs.rs. Generate documentation about supported platforms automatically from the `cfg` attributes. --- Cargo.toml | 19 ++- src/lib.rs | 50 +----- src/socket.rs | 110 ------------- src/sockref.rs | 2 - src/sys/unix.rs | 400 --------------------------------------------- src/sys/windows.rs | 8 - 6 files changed, 19 insertions(+), 570 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c8656f05..18331f61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,8 +29,23 @@ include = [ [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] -targets = ["aarch64-apple-ios", "aarch64-linux-android", "x86_64-apple-darwin", "x86_64-unknown-fuchsia", "x86_64-pc-windows-msvc", "x86_64-pc-solaris", "x86_64-unknown-freebsd", "x86_64-unknown-illumos", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl", "x86_64-unknown-netbsd", "x86_64-unknown-redox", "armv7-linux-androideabi", "i686-linux-android"] +default-target = "x86_64-unknown-linux-gnu" +targets = [ + "aarch64-apple-ios", + "aarch64-linux-android", + "armv7-linux-androideabi", + "i686-linux-android", + "x86_64-apple-darwin", + "x86_64-pc-solaris", + "x86_64-pc-windows-msvc", + "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", + "x86_64-unknown-illumos", + "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", + "x86_64-unknown-netbsd", + "x86_64-unknown-redox", +] [package.metadata.playground] features = ["all"] diff --git a/src/lib.rs b/src/lib.rs index 8f593163..946714ae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,8 +51,8 @@ //! that are not available on all OSs. #![deny(missing_docs, missing_debug_implementations, rust_2018_idioms)] -// Show required OS/features on docs.rs. -#![cfg_attr(docsrs, feature(doc_cfg))] +// Automatically generate required OS/features for docs.rs. +#![cfg_attr(docsrs, feature(doc_auto_cfg))] // Disallow warnings when running tests. #![cfg_attr(test, deny(warnings))] // Disallow warnings in examples. @@ -266,20 +266,14 @@ impl Type { /// /// Used for the DCCP protocol. #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub const DCCP: Type = Type(sys::SOCK_DCCP); /// Type corresponding to `SOCK_SEQPACKET`. #[cfg(all(feature = "all", not(target_os = "espidf")))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", not(target_os = "espidf")))))] pub const SEQPACKET: Type = Type(sys::SOCK_SEQPACKET); /// Type corresponding to `SOCK_RAW`. #[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))] - #[cfg_attr( - docsrs, - doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) - )] pub const RAW: Type = Type(sys::SOCK_RAW); } @@ -324,7 +318,6 @@ impl Protocol { /// Protocol corresponding to `DCCP`. #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub const DCCP: Protocol = Protocol(sys::IPPROTO_DCCP); /// Protocol corresponding to `SCTP`. @@ -364,7 +357,6 @@ impl From for c_int { /// /// Flags provide additional information about incoming messages. #[cfg(not(target_os = "redox"))] -#[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))] #[derive(Copy, Clone, Eq, PartialEq)] pub struct RecvFlags(c_int); @@ -523,24 +515,6 @@ impl TcpKeepalive { target_os = "watchos", target_os = "windows", ))] - #[cfg_attr( - docsrs, - doc(cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "visionos", - target_os = "linux", - target_os = "macos", - target_os = "netbsd", - target_os = "tvos", - target_os = "watchos", - target_os = "windows", - ))) - )] pub const fn with_interval(self, interval: Duration) -> Self { Self { interval: Some(interval), @@ -569,26 +543,6 @@ impl TcpKeepalive { target_os = "watchos", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "visionos", - target_os = "linux", - target_os = "macos", - target_os = "netbsd", - target_os = "tvos", - target_os = "watchos", - ) - ))) - )] pub const fn with_retries(self, retries: u32) -> Self { Self { retries: Some(retries), diff --git a/src/socket.rs b/src/socket.rs index e6cdca24..1bed96f5 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -150,7 +150,6 @@ impl Socket { /// [`Socket::pair_raw`] can be used if you don't want to set those flags. #[doc = man_links!(unix: socketpair(2))] #[cfg(all(feature = "all", unix))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", unix))))] pub fn pair( domain: Domain, ty: Type, @@ -167,7 +166,6 @@ impl Socket { /// /// This function corresponds to `socketpair(2)`. #[cfg(all(feature = "all", unix))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", unix))))] pub fn pair_raw( domain: Domain, ty: Type, @@ -369,7 +367,6 @@ impl Socket { /// /// On Windows it is not possible retrieve the nonblocking mode status. #[cfg(all(feature = "all", unix))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", unix))))] pub fn nonblocking(&self) -> io::Result { sys::nonblocking(self.as_raw()) } @@ -471,7 +468,6 @@ impl Socket { /// function with `buf`s of type `&mut [IoSliceMut]`, allowing initialised /// buffers to be used without using `unsafe`. #[cfg(not(target_os = "redox"))] - #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))] pub fn recv_vectored( &self, bufs: &mut [MaybeUninitSlice<'_>], @@ -491,7 +487,6 @@ impl Socket { /// /// [`recv_vectored`]: Socket::recv_vectored #[cfg(not(target_os = "redox"))] - #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))] pub fn recv_vectored_with_flags( &self, bufs: &mut [MaybeUninitSlice<'_>], @@ -557,7 +552,6 @@ impl Socket { /// /// [`recv_vectored`]: Socket::recv_vectored #[cfg(not(target_os = "redox"))] - #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))] pub fn recv_from_vectored( &self, bufs: &mut [MaybeUninitSlice<'_>], @@ -577,7 +571,6 @@ impl Socket { /// /// [`recv_vectored`]: Socket::recv_vectored #[cfg(not(target_os = "redox"))] - #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))] pub fn recv_from_vectored_with_flags( &self, bufs: &mut [MaybeUninitSlice<'_>], @@ -637,7 +630,6 @@ impl Socket { /// for an example (in C++). #[doc = man_links!(recvmsg(2))] #[cfg(all(unix, not(target_os = "redox")))] - #[cfg_attr(docsrs, doc(cfg(all(unix, not(target_os = "redox")))))] pub fn recvmsg(&self, msg: &mut MsgHdrMut<'_, '_, '_>, flags: sys::c_int) -> io::Result { sys::recvmsg(self.as_raw(), msg, flags) } @@ -663,7 +655,6 @@ impl Socket { /// Send data to the connected peer. Returns the amount of bytes written. #[cfg(not(target_os = "redox"))] - #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))] pub fn send_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { self.send_vectored_with_flags(bufs, 0) } @@ -674,7 +665,6 @@ impl Socket { /// /// [`send_vectored`]: Socket::send_vectored #[cfg(not(target_os = "redox"))] - #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))] pub fn send_vectored_with_flags( &self, bufs: &[IoSlice<'_>], @@ -721,7 +711,6 @@ impl Socket { /// written. #[doc = man_links!(sendmsg(2))] #[cfg(not(target_os = "redox"))] - #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))] pub fn send_to_vectored(&self, bufs: &[IoSlice<'_>], addr: &SockAddr) -> io::Result { self.send_to_vectored_with_flags(bufs, addr, 0) } @@ -731,7 +720,6 @@ impl Socket { /// /// [`send_to_vectored`]: Socket::send_to_vectored #[cfg(not(target_os = "redox"))] - #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))] pub fn send_to_vectored_with_flags( &self, bufs: &[IoSlice<'_>], @@ -744,7 +732,6 @@ impl Socket { /// Send a message on a socket using a message structure. #[doc = man_links!(sendmsg(2))] #[cfg(not(target_os = "redox"))] - #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))] pub fn sendmsg(&self, msg: &MsgHdr<'_, '_, '_>, flags: sys::c_int) -> io::Result { sys::sendmsg(self.as_raw(), msg, flags) } @@ -939,7 +926,6 @@ impl Socket { /// /// [`set_out_of_band_inline`]: Socket::set_out_of_band_inline #[cfg(not(target_os = "redox"))] - #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))] pub fn out_of_band_inline(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::SOL_SOCKET, sys::SO_OOBINLINE) @@ -954,7 +940,6 @@ impl Socket { /// `MSG_OOB` flag is set during receiving. As per RFC6093, TCP sockets /// using the Urgent mechanism are encouraged to set this flag. #[cfg(not(target_os = "redox"))] - #[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))] pub fn set_out_of_band_inline(&self, oob_inline: bool) -> io::Result<()> { unsafe { setsockopt( @@ -972,7 +957,6 @@ impl Socket { /// /// [`set_passcred`]: Socket::set_passcred #[cfg(all(unix, target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(unix, target_os = "linux"))))] pub fn passcred(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::SOL_SOCKET, sys::SO_PASSCRED) @@ -985,7 +969,6 @@ impl Socket { /// If this option is enabled, enables the receiving of the `SCM_CREDENTIALS` /// control messages. #[cfg(all(unix, target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(unix, target_os = "linux"))))] pub fn set_passcred(&self, passcred: bool) -> io::Result<()> { unsafe { setsockopt( @@ -1145,10 +1128,6 @@ impl Socket { /// /// [`set_header_included_v4`]: Socket::set_header_included_v4 #[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))] - #[cfg_attr( - docsrs, - doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) - )] pub fn header_included_v4(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_IP, sys::IP_HDRINCL) @@ -1172,10 +1151,6 @@ impl Socket { allow(rustdoc::broken_intra_doc_links) )] #[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))] - #[cfg_attr( - docsrs, - doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) - )] pub fn set_header_included_v4(&self, included: bool) -> io::Result<()> { unsafe { setsockopt( @@ -1193,7 +1168,6 @@ impl Socket { /// /// [`set_ip_transparent_v4`]: Socket::set_ip_transparent_v4 #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn ip_transparent_v4(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_IP, libc::IP_TRANSPARENT) @@ -1217,7 +1191,6 @@ impl 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"))))] pub fn set_ip_transparent_v4(&self, transparent: bool) -> io::Result<()> { unsafe { setsockopt( @@ -1415,7 +1388,6 @@ impl Socket { /// /// [`set_multicast_all_v4`]: Socket::set_multicast_all_v4 #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn multicast_all_v4(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_IP, libc::IP_MULTICAST_ALL) @@ -1434,7 +1406,6 @@ impl Socket { /// joined (for example via the `IP_ADD_MEMBERSHIP` option) on /// this particular socket. #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn set_multicast_all_v4(&self, all: bool) -> io::Result<()> { unsafe { setsockopt( @@ -1668,10 +1639,6 @@ impl Socket { target_os = "netbsd" )) ))] - #[cfg_attr( - docsrs, - doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) - )] pub fn header_included_v6(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_IPV6, sys::IP_HDRINCL) @@ -1702,10 +1669,6 @@ impl Socket { target_os = "netbsd" )) ))] - #[cfg_attr( - docsrs, - doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))) - )] pub fn set_header_included_v6(&self, included: bool) -> io::Result<()> { unsafe { setsockopt( @@ -1799,7 +1762,6 @@ impl Socket { /// /// [`set_multicast_all_v6`]: Socket::set_multicast_all_v6 #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn multicast_all_v6(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_IPV6, libc::IPV6_MULTICAST_ALL) @@ -1818,7 +1780,6 @@ impl Socket { /// joined (for example via the `IPV6_ADD_MEMBERSHIP` option) on /// this particular socket. #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn set_multicast_all_v6(&self, all: bool) -> io::Result<()> { unsafe { setsockopt( @@ -2075,18 +2036,6 @@ impl Socket { target_os = "vita" )) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - not(any( - windows, - target_os = "haiku", - target_os = "openbsd", - target_os = "vita" - )) - ))) - )] pub fn keepalive_time(&self) -> io::Result { sys::keepalive_time(self.as_raw()) } @@ -2113,26 +2062,6 @@ impl Socket { target_os = "watchos", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "visionos", - target_os = "linux", - target_os = "macos", - target_os = "netbsd", - target_os = "tvos", - target_os = "watchos", - ) - ))) - )] pub fn keepalive_interval(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_TCP, sys::TCP_KEEPINTVL) @@ -2162,26 +2091,6 @@ impl Socket { target_os = "watchos", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "visionos", - target_os = "linux", - target_os = "macos", - target_os = "netbsd", - target_os = "tvos", - target_os = "watchos", - ) - ))) - )] pub fn keepalive_retries(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_TCP, sys::TCP_KEEPCNT) @@ -2272,18 +2181,6 @@ impl Socket { target_os = "windows", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "android", - target_os = "fuchsia", - target_os = "linux", - target_os = "windows", - ) - ))) - )] pub fn original_dst(&self) -> io::Result { sys::original_dst(self.as_raw()) } @@ -2293,13 +2190,6 @@ impl Socket { feature = "all", any(target_os = "android", target_os = "linux", target_os = "windows") ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any(target_os = "android", target_os = "linux", target_os = "windows") - ))) - )] pub fn original_dst_ipv6(&self) -> io::Result { sys::original_dst_ipv6(self.as_raw()) } diff --git a/src/sockref.rs b/src/sockref.rs index 94b84dd4..59353b15 100644 --- a/src/sockref.rs +++ b/src/sockref.rs @@ -78,7 +78,6 @@ impl<'s> Deref for SockRef<'s> { /// On Windows, a corresponding `From<&impl AsSocket>` implementation exists. #[cfg(unix)] -#[cfg_attr(docsrs, doc(cfg(unix)))] impl<'s, S> From<&'s S> for SockRef<'s> where S: AsFd, @@ -96,7 +95,6 @@ where /// On Unix, a corresponding `From<&impl AsFd>` implementation exists. #[cfg(windows)] -#[cfg_attr(docsrs, doc(cfg(windows)))] impl<'s, S> From<&'s S> for SockRef<'s> where S: AsSocket, diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 05cb2e91..c187d517 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -389,21 +389,10 @@ impl Domain { 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 const PACKET: Domain = Domain(libc::AF_PACKET); /// Domain for low-level VSOCK interface, corresponding to `AF_VSOCK`. #[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 const VSOCK: Domain = Domain(libc::AF_VSOCK); } @@ -413,13 +402,8 @@ impl_debug!( libc::AF_INET6, libc::AF_UNIX, #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] - #[cfg_attr( - docsrs, - doc(cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))) - )] libc::AF_PACKET, #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(any(target_os = "android", target_os = "linux"))))] libc::AF_VSOCK, libc::AF_UNSPEC, // = 0. ); @@ -440,22 +424,6 @@ impl Type { target_os = "openbsd" ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd" - ) - ))) - )] pub const fn nonblocking(self) -> Type { Type(self.0 | libc::SOCK_NONBLOCK) } @@ -477,25 +445,6 @@ impl Type { target_os = "solaris", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "hurd", - target_os = "illumos", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - target_os = "solaris", - ) - ))) - )] pub const fn cloexec(self) -> Type { self._cloexec() } @@ -615,10 +564,6 @@ impl RecvFlags { /// /// On Unix this corresponds to the `MSG_CONFIRM` flag. #[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 const fn is_confirm(self) -> bool { self.0 & libc::MSG_CONFIRM != 0 } @@ -630,10 +575,6 @@ impl RecvFlags { /// /// On Unix this corresponds to the `MSG_DONTROUTE` flag. #[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 const fn is_dontroute(self) -> bool { self.0 & libc::MSG_DONTROUTE != 0 } @@ -786,10 +727,6 @@ impl SockAddr { /// infallible. #[allow(unsafe_op_in_unsafe_fn)] #[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 vsock(cid: u32, port: u32) -> SockAddr { // SAFETY: a `sockaddr_storage` of all zeros is valid. let mut storage = unsafe { mem::zeroed::() }; @@ -806,10 +743,6 @@ impl SockAddr { /// Returns this address VSOCK CID/port if it is in the `AF_VSOCK` family, /// otherwise return `None`. #[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 as_vsock_address(&self) -> Option<(u32, u32)> { if self.family() == libc::AF_VSOCK as sa_family_t { // Safety: if the ss_family field is AF_VSOCK then storage must be a sockaddr_vm. @@ -934,7 +867,6 @@ pub(crate) fn socket(family: c_int, ty: c_int, protocol: c_int) -> io::Result io::Result<[Socket; 2]> { let mut fds = [0, 0]; syscall!(socketpair(family, ty, protocol, fds.as_mut_ptr())).map(|_| fds) @@ -1229,13 +1161,6 @@ fn into_timeval(duration: Option) -> libc::timeval { feature = "all", not(any(target_os = "haiku", target_os = "openbsd", target_os = "vita")) ))] -#[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - not(any(target_os = "haiku", target_os = "openbsd", target_os = "vita")) - ))) -)] pub(crate) fn keepalive_time(fd: Socket) -> io::Result { unsafe { getsockopt::(fd, IPPROTO_TCP, KEEPALIVE_TIME) @@ -1487,22 +1412,6 @@ impl crate::Socket { target_os = "openbsd", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - ) - ))) - )] pub fn accept4(&self, flags: c_int) -> io::Result<(crate::Socket, SockAddr)> { self._accept4(flags) } @@ -1543,7 +1452,6 @@ impl crate::Socket { allow(rustdoc::broken_intra_doc_links) )] #[cfg(all(feature = "all", not(target_os = "vita")))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", unix))))] pub fn set_cloexec(&self, close_on_exec: bool) -> io::Result<()> { self._set_cloexec(close_on_exec) } @@ -1578,19 +1486,6 @@ impl crate::Socket { target_os = "watchos", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "ios", - target_os = "visionos", - target_os = "macos", - target_os = "tvos", - target_os = "watchos", - ) - ))) - )] pub fn set_nosigpipe(&self, nosigpipe: bool) -> io::Result<()> { self._set_nosigpipe(nosigpipe) } @@ -1619,7 +1514,6 @@ impl crate::Socket { /// /// [`set_mss`]: crate::Socket::set_mss #[cfg(all(feature = "all", not(target_os = "redox")))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", unix, not(target_os = "redox")))))] pub fn mss(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::IPPROTO_TCP, libc::TCP_MAXSEG) @@ -1632,7 +1526,6 @@ impl crate::Socket { /// The `TCP_MAXSEG` option denotes the TCP Maximum Segment Size and is only /// available on TCP sockets. #[cfg(all(feature = "all", not(target_os = "redox")))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", unix, not(target_os = "redox")))))] pub fn set_mss(&self, mss: u32) -> io::Result<()> { unsafe { setsockopt( @@ -1656,19 +1549,6 @@ impl crate::Socket { target_os = "linux", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "aix", - target_os = "android", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "linux", - ) - ))) - )] pub fn is_listener(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::SOL_SOCKET, libc::SO_ACCEPTCONN) @@ -1688,16 +1568,6 @@ impl crate::Socket { target_os = "linux", ) ))] - #[cfg_attr(docsrs, doc(cfg(all( - feature = "all", - any( - target_os = "android", - // TODO: add FreeBSD. - // target_os = "freebsd", - target_os = "fuchsia", - target_os = "linux", - ) - ))))] pub fn domain(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::SOL_SOCKET, libc::SO_DOMAIN).map(Domain) } } @@ -1713,18 +1583,6 @@ impl crate::Socket { target_os = "linux", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "android", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "linux", - ) - ))) - )] pub fn protocol(&self) -> io::Result> { unsafe { getsockopt::(self.as_raw(), libc::SOL_SOCKET, libc::SO_PROTOCOL).map(|v| match v @@ -1745,13 +1603,6 @@ impl crate::Socket { 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 mark(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::SOL_SOCKET, libc::SO_MARK) @@ -1770,13 +1621,6 @@ impl crate::Socket { 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_mark(&self, mark: u32) -> io::Result<()> { unsafe { setsockopt::( @@ -1797,13 +1641,6 @@ impl crate::Socket { 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 cork(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::IPPROTO_TCP, libc::TCP_CORK) @@ -1821,13 +1658,6 @@ impl crate::Socket { 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_cork(&self, cork: bool) -> io::Result<()> { unsafe { setsockopt( @@ -1848,13 +1678,6 @@ impl crate::Socket { 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 quickack(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::IPPROTO_TCP, libc::TCP_QUICKACK) @@ -1872,13 +1695,6 @@ impl crate::Socket { 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_quickack(&self, quickack: bool) -> io::Result<()> { unsafe { setsockopt( @@ -1899,13 +1715,6 @@ impl crate::Socket { 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 thin_linear_timeouts(&self) -> io::Result { unsafe { getsockopt::( @@ -1926,13 +1735,6 @@ impl crate::Socket { 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_thin_linear_timeouts(&self, timeouts: bool) -> io::Result<()> { unsafe { setsockopt( @@ -1951,13 +1753,6 @@ impl crate::Socket { 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 device(&self) -> io::Result>> { // TODO: replace with `MaybeUninit::uninit_array` once stable. let mut buf: [MaybeUninit; libc::IFNAMSIZ] = @@ -1990,13 +1785,6 @@ impl crate::Socket { 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 bind_device(&self, interface: Option<&[u8]>) -> io::Result<()> { let (value, len) = if let Some(interface) = interface { (interface.as_ptr(), interface.len()) @@ -2017,7 +1805,6 @@ impl crate::Socket { /// /// Bind socket to the specified forwarding table (VRF) on a FreeBSD. #[cfg(all(feature = "all", target_os = "freebsd"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "freebsd"))))] pub fn set_fib(&self, fib: u32) -> io::Result<()> { syscall!(setsockopt( self.as_raw(), @@ -2049,19 +1836,6 @@ impl crate::Socket { target_os = "watchos", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "ios", - target_os = "visionos", - target_os = "macos", - target_os = "tvos", - target_os = "watchos", - ) - ))) - )] pub fn bind_device_by_index_v4(&self, interface: Option) -> io::Result<()> { let index = interface.map_or(0, NonZeroU32::get); unsafe { setsockopt(self.as_raw(), IPPROTO_IP, libc::IP_BOUND_IF, index) } @@ -2087,19 +1861,6 @@ impl crate::Socket { target_os = "watchos", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "ios", - target_os = "visionos", - target_os = "macos", - target_os = "tvos", - target_os = "watchos", - ) - ))) - )] pub fn bind_device_by_index_v6(&self, interface: Option) -> io::Result<()> { let index = interface.map_or(0, NonZeroU32::get); unsafe { setsockopt(self.as_raw(), IPPROTO_IPV6, libc::IPV6_BOUND_IF, index) } @@ -2120,19 +1881,6 @@ impl crate::Socket { target_os = "watchos", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "ios", - target_os = "visionos", - target_os = "macos", - target_os = "tvos", - target_os = "watchos", - ) - ))) - )] pub fn device_index_v4(&self) -> io::Result> { let index = unsafe { getsockopt::(self.as_raw(), IPPROTO_IP, libc::IP_BOUND_IF)? }; @@ -2154,19 +1902,6 @@ impl crate::Socket { target_os = "watchos", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "ios", - target_os = "visionos", - target_os = "macos", - target_os = "tvos", - target_os = "watchos", - ) - ))) - )] pub fn device_index_v6(&self) -> io::Result> { let index = unsafe { getsockopt::(self.as_raw(), IPPROTO_IPV6, libc::IPV6_BOUND_IF)? @@ -2180,7 +1915,6 @@ impl crate::Socket { /// /// [`set_cpu_affinity`]: crate::Socket::set_cpu_affinity #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn cpu_affinity(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::SOL_SOCKET, libc::SO_INCOMING_CPU) @@ -2192,7 +1926,6 @@ impl crate::Socket { /// /// Sets the CPU affinity of the socket. #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn set_cpu_affinity(&self, cpu: usize) -> io::Result<()> { unsafe { setsockopt( @@ -2213,14 +1946,6 @@ impl crate::Socket { feature = "all", not(any(target_os = "solaris", target_os = "illumos")) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - unix, - not(any(target_os = "solaris", target_os = "illumos")) - ))) - )] pub fn reuse_port(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::SOL_SOCKET, libc::SO_REUSEPORT) @@ -2237,14 +1962,6 @@ impl crate::Socket { feature = "all", not(any(target_os = "solaris", target_os = "illumos")) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - unix, - not(any(target_os = "solaris", target_os = "illumos")) - ))) - )] pub fn set_reuse_port(&self, reuse: bool) -> io::Result<()> { unsafe { setsockopt( @@ -2294,13 +2011,6 @@ impl crate::Socket { 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 freebind(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::SOL_IP, libc::IP_FREEBIND) @@ -2319,13 +2029,6 @@ impl crate::Socket { 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_freebind(&self, freebind: bool) -> io::Result<()> { unsafe { setsockopt( @@ -2345,10 +2048,6 @@ impl crate::Socket { /// /// [`set_freebind`]: crate::Socket::set_freebind #[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 freebind_ipv6(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::SOL_IPV6, libc::IPV6_FREEBIND) @@ -2387,10 +2086,6 @@ impl crate::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_freebind_ipv6(&self, freebind: bool) -> io::Result<()> { unsafe { setsockopt( @@ -2435,23 +2130,6 @@ impl crate::Socket { target_os = "watchos", ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "aix", - target_os = "android", - target_os = "freebsd", - target_os = "ios", - target_os = "visionos", - target_os = "linux", - target_os = "macos", - target_os = "tvos", - target_os = "watchos", - ) - ))) - )] pub fn sendfile( &self, file: &F, @@ -2584,13 +2262,6 @@ impl crate::Socket { 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_tcp_user_timeout(&self, timeout: Option) -> io::Result<()> { let timeout = timeout.map_or(0, |to| { min(to.as_millis(), libc::c_uint::MAX as u128) as libc::c_uint @@ -2614,13 +2285,6 @@ impl crate::Socket { 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 tcp_user_timeout(&self) -> io::Result> { unsafe { getsockopt::(self.as_raw(), libc::IPPROTO_TCP, libc::TCP_USER_TIMEOUT) @@ -2674,7 +2338,6 @@ impl crate::Socket { /// /// For more information about this option, see [Linux patch](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5daab9db7b65df87da26fd8cfa695fb9546a1ddb) #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn cookie(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::SOL_SOCKET, libc::SO_COOKIE) } } @@ -2697,22 +2360,6 @@ impl crate::Socket { target_os = "openbsd" ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "linux", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd" - ) - ))) - )] pub fn tclass_v6(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), IPPROTO_IPV6, libc::IPV6_TCLASS) @@ -2737,22 +2384,6 @@ impl crate::Socket { target_os = "openbsd" ) ))] - #[cfg_attr( - docsrs, - doc(cfg(all( - feature = "all", - any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "linux", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd" - ) - ))) - )] pub fn set_tclass_v6(&self, tclass: u32) -> io::Result<()> { unsafe { setsockopt( @@ -2770,10 +2401,6 @@ impl crate::Socket { /// /// [`set_tcp_congestion`]: crate::Socket::set_tcp_congestion #[cfg(all(feature = "all", any(target_os = "freebsd", target_os = "linux")))] - #[cfg_attr( - docsrs, - doc(cfg(all(feature = "all", any(target_os = "freebsd", target_os = "linux")))) - )] pub fn tcp_congestion(&self) -> io::Result> { let mut payload: [u8; TCP_CA_NAME_MAX] = [0; TCP_CA_NAME_MAX]; let mut len = payload.len() as libc::socklen_t; @@ -2794,10 +2421,6 @@ impl crate::Socket { /// The value must be a valid TCP congestion control algorithm name of the /// platform. For example, Linux may supports "reno", "cubic". #[cfg(all(feature = "all", any(target_os = "freebsd", target_os = "linux")))] - #[cfg_attr( - docsrs, - doc(cfg(all(feature = "all", any(target_os = "freebsd", target_os = "linux")))) - )] pub fn set_tcp_congestion(&self, tcp_ca_name: &[u8]) -> io::Result<()> { syscall!(setsockopt( self.as_raw(), @@ -2820,7 +2443,6 @@ impl crate::Socket { /// [`connect`]: crate::Socket::connect /// [`bind`]: crate::Socket::bind #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn set_dccp_service(&self, code: u32) -> io::Result<()> { unsafe { setsockopt( @@ -2838,7 +2460,6 @@ impl crate::Socket { /// /// [`set_dccp_service`]: crate::Socket::set_dccp_service #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn dccp_service(&self) -> io::Result { unsafe { getsockopt(self.as_raw(), libc::SOL_DCCP, libc::DCCP_SOCKOPT_SERVICE) } } @@ -2847,7 +2468,6 @@ impl crate::Socket { /// /// This option sets both the TX and RX CCIDs at the same time. #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn set_dccp_ccid(&self, ccid: u8) -> io::Result<()> { unsafe { setsockopt(self.as_raw(), libc::SOL_DCCP, libc::DCCP_SOCKOPT_CCID, ccid) } } @@ -2858,7 +2478,6 @@ impl crate::Socket { /// /// [`set_dccp_ccid`]: crate::Socket::set_dccp_ccid #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn dccp_tx_ccid(&self) -> io::Result { unsafe { getsockopt(self.as_raw(), libc::SOL_DCCP, libc::DCCP_SOCKOPT_TX_CCID) } } @@ -2869,7 +2488,6 @@ impl crate::Socket { /// /// [`set_dccp_ccid`]: crate::Socket::set_dccp_ccid #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn dccp_xx_ccid(&self) -> io::Result { unsafe { getsockopt(self.as_raw(), libc::SOL_DCCP, libc::DCCP_SOCKOPT_RX_CCID) } } @@ -2879,7 +2497,6 @@ impl crate::Socket { /// Enables a listening socket to hold timewait state when closing the /// connection. This option must be set after `accept` returns. #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn set_dccp_server_timewait(&self, hold_timewait: bool) -> io::Result<()> { unsafe { setsockopt( @@ -2897,7 +2514,6 @@ impl crate::Socket { /// /// [`set_dccp_server_timewait`]: crate::Socket::set_dccp_server_timewait #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn dccp_server_timewait(&self) -> io::Result { unsafe { getsockopt( @@ -2916,7 +2532,6 @@ impl crate::Socket { /// accepted by the receiver. Hence, when using this feature on the sender, /// it must be enabled at the receiver too, with suitable choice of CsCov. #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn set_dccp_send_cscov(&self, level: u32) -> io::Result<()> { unsafe { setsockopt( @@ -2934,7 +2549,6 @@ impl crate::Socket { /// /// [`set_dccp_send_cscov`]: crate::Socket::set_dccp_send_cscov #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn dccp_send_cscov(&self) -> io::Result { unsafe { getsockopt(self.as_raw(), libc::SOL_DCCP, libc::DCCP_SOCKOPT_SEND_CSCOV) } } @@ -2945,7 +2559,6 @@ impl crate::Socket { /// /// [`set_dccp_send_cscov`]: crate::Socket::set_dccp_send_cscov #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn set_dccp_recv_cscov(&self, level: u32) -> io::Result<()> { unsafe { setsockopt( @@ -2963,7 +2576,6 @@ impl crate::Socket { /// /// [`set_dccp_recv_cscov`]: crate::Socket::set_dccp_recv_cscov #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn dccp_recv_cscov(&self) -> io::Result { unsafe { getsockopt(self.as_raw(), libc::SOL_DCCP, libc::DCCP_SOCKOPT_RECV_CSCOV) } } @@ -2973,7 +2585,6 @@ impl crate::Socket { /// This option sets the maximum length of the output queue. A zero value is /// interpreted as unbounded queue length. #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn set_dccp_qpolicy_txqlen(&self, length: u32) -> io::Result<()> { unsafe { setsockopt( @@ -2991,7 +2602,6 @@ impl crate::Socket { /// /// [`set_dccp_qpolicy_txqlen`]: crate::Socket::set_dccp_qpolicy_txqlen #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn dccp_qpolicy_txqlen(&self) -> io::Result { unsafe { getsockopt( @@ -3012,7 +2622,6 @@ impl crate::Socket { /// /// [documentation]: https://www.kernel.org/doc/html/latest/networking/dccp.html #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn dccp_available_ccids(&self) -> io::Result> { let mut endpoints = [0; N]; let mut length = endpoints.len() as libc::socklen_t; @@ -3031,7 +2640,6 @@ impl crate::Socket { /// This option retrieves the current maximum packet size (application /// payload size) in bytes. #[cfg(all(feature = "all", target_os = "linux"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] pub fn dccp_cur_mps(&self) -> io::Result { unsafe { getsockopt( @@ -3045,7 +2653,6 @@ impl crate::Socket { /// See [`Socket::dccp_available_ccids`]. #[cfg(all(feature = "all", target_os = "linux"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] #[derive(Debug)] pub struct CcidEndpoints { endpoints: [u8; N], @@ -3053,7 +2660,6 @@ pub struct CcidEndpoints { } #[cfg(all(feature = "all", target_os = "linux"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] impl std::ops::Deref for CcidEndpoints { type Target = [u8]; @@ -3062,7 +2668,6 @@ impl std::ops::Deref for CcidEndpoints { } } -#[cfg_attr(docsrs, doc(cfg(unix)))] impl AsFd for crate::Socket { fn as_fd(&self) -> BorrowedFd<'_> { // SAFETY: lifetime is bound by self. @@ -3070,14 +2675,12 @@ impl AsFd for crate::Socket { } } -#[cfg_attr(docsrs, doc(cfg(unix)))] impl AsRawFd for crate::Socket { fn as_raw_fd(&self) -> c_int { self.as_raw() } } -#[cfg_attr(docsrs, doc(cfg(unix)))] impl From for OwnedFd { fn from(sock: crate::Socket) -> OwnedFd { // SAFETY: sock.into_raw() always returns a valid fd. @@ -3085,14 +2688,12 @@ impl From for OwnedFd { } } -#[cfg_attr(docsrs, doc(cfg(unix)))] impl IntoRawFd for crate::Socket { fn into_raw_fd(self) -> c_int { self.into_raw() } } -#[cfg_attr(docsrs, doc(cfg(unix)))] impl From for crate::Socket { fn from(fd: OwnedFd) -> crate::Socket { // SAFETY: `OwnedFd` ensures the fd is valid. @@ -3100,7 +2701,6 @@ impl From for crate::Socket { } } -#[cfg_attr(docsrs, doc(cfg(unix)))] impl FromRawFd for crate::Socket { unsafe fn from_raw_fd(fd: c_int) -> crate::Socket { crate::Socket::from_raw(fd) diff --git a/src/sys/windows.rs b/src/sys/windows.rs index 8cf27b53..10852f19 100644 --- a/src/sys/windows.rs +++ b/src/sys/windows.rs @@ -125,7 +125,6 @@ impl Type { /// Set `WSA_FLAG_NO_HANDLE_INHERIT` on the socket. #[cfg(feature = "all")] - #[cfg_attr(docsrs, doc(cfg(all(windows, feature = "all"))))] pub const fn no_inherit(self) -> Type { self._no_inherit() } @@ -946,7 +945,6 @@ pub(crate) fn unix_sockaddr(path: &Path) -> io::Result { impl crate::Socket { /// Sets `HANDLE_FLAG_INHERIT` using `SetHandleInformation`. #[cfg(feature = "all")] - #[cfg_attr(docsrs, doc(cfg(all(windows, feature = "all"))))] pub fn set_no_inherit(&self, no_inherit: bool) -> io::Result<()> { self._set_no_inherit(no_inherit) } @@ -985,7 +983,6 @@ impl crate::Socket { } } -#[cfg_attr(docsrs, doc(cfg(windows)))] impl AsSocket for crate::Socket { fn as_socket(&self) -> BorrowedSocket<'_> { // SAFETY: lifetime is bound by self. @@ -993,14 +990,12 @@ impl AsSocket for crate::Socket { } } -#[cfg_attr(docsrs, doc(cfg(windows)))] impl AsRawSocket for crate::Socket { fn as_raw_socket(&self) -> RawSocket { self.as_raw() as RawSocket } } -#[cfg_attr(docsrs, doc(cfg(windows)))] impl From for OwnedSocket { fn from(sock: crate::Socket) -> OwnedSocket { // SAFETY: sock.into_raw() always returns a valid fd. @@ -1008,14 +1003,12 @@ impl From for OwnedSocket { } } -#[cfg_attr(docsrs, doc(cfg(windows)))] impl IntoRawSocket for crate::Socket { fn into_raw_socket(self) -> RawSocket { self.into_raw() as RawSocket } } -#[cfg_attr(docsrs, doc(cfg(windows)))] impl From for crate::Socket { fn from(fd: OwnedSocket) -> crate::Socket { // SAFETY: `OwnedFd` ensures the fd is valid. @@ -1023,7 +1016,6 @@ impl From for crate::Socket { } } -#[cfg_attr(docsrs, doc(cfg(windows)))] impl FromRawSocket for crate::Socket { unsafe fn from_raw_socket(socket: RawSocket) -> crate::Socket { crate::Socket::from_raw(socket as Socket) From 34aba73afdbcd4e3dbf0fa9ff9ece889e77926ab Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Mon, 24 Feb 2025 11:20:44 +0100 Subject: [PATCH 29/33] Ignore clippy::needless-lifetimes (#544) The lifetimes serve as documentation. --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 946714ae..4d39b05d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(clippy::needless_lifetimes)] + //! Utilities for creating and using sockets. //! //! The goal of this crate is to create and use a socket using advanced From 5c1f3b09897d251b8a10f690af71af13cc7d32ca Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Tue, 11 Mar 2025 14:51:06 -0700 Subject: [PATCH 30/33] Enable `IP_BOUND_IF` on illumos and Solaris (#561) The `IP_BOUND_IF` socket option, which is wrapped by the `Socket::bind_device_by_index_{v4,v6}` and `Socket::device_index_{v4,v6}` is available on SunOS-like systems, such as illumos and Solaris, as well as macOS-like systems. However, these APIs are currently cfg-flagged to only be available on macOS-like systems. This commit changes the cfg attributes to also enable these APIs on illumos and Solaris. Fixes #560 --- Cargo.toml | 2 +- src/sys/unix.rs | 10 ++++++++++ tests/socket.rs | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 18331f61..d0566282 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ targets = [ features = ["all"] [target."cfg(unix)".dependencies] -libc = "0.2.150" +libc = "0.2.171" [target.'cfg(windows)'.dependencies.windows-sys] version = "0.52" diff --git a/src/sys/unix.rs b/src/sys/unix.rs index c187d517..37d0c3a6 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -22,6 +22,8 @@ use std::net::{Ipv4Addr, Ipv6Addr}; target_os = "macos", target_os = "tvos", target_os = "watchos", + target_os = "illumos", + target_os = "solaris", ) ))] use std::num::NonZeroU32; @@ -1834,6 +1836,8 @@ impl crate::Socket { target_os = "macos", target_os = "tvos", target_os = "watchos", + target_os = "illumos", + target_os = "solaris", ) ))] pub fn bind_device_by_index_v4(&self, interface: Option) -> io::Result<()> { @@ -1859,6 +1863,8 @@ impl crate::Socket { target_os = "macos", target_os = "tvos", target_os = "watchos", + target_os = "illumos", + target_os = "solaris", ) ))] pub fn bind_device_by_index_v6(&self, interface: Option) -> io::Result<()> { @@ -1879,6 +1885,8 @@ impl crate::Socket { target_os = "macos", target_os = "tvos", target_os = "watchos", + target_os = "illumos", + target_os = "solaris", ) ))] pub fn device_index_v4(&self) -> io::Result> { @@ -1900,6 +1908,8 @@ impl crate::Socket { target_os = "macos", target_os = "tvos", target_os = "watchos", + target_os = "illumos", + target_os = "solaris", ) ))] pub fn device_index_v6(&self) -> io::Result> { diff --git a/tests/socket.rs b/tests/socket.rs index 3776a4b4..a2dca668 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -990,6 +990,8 @@ fn device() { target_os = "macos", target_os = "tvos", target_os = "watchos", + target_os = "solaris", + target_os = "illumos", ) ))] #[test] @@ -1036,6 +1038,8 @@ fn device() { target_os = "macos", target_os = "tvos", target_os = "watchos", + target_os = "solaris", + target_os = "illumos", ) ))] #[test] From d35ef3077a0b66d4a5f3afb7354dc56e5a9f9e6a Mon Sep 17 00:00:00 2001 From: kntyskw Date: Sun, 16 Mar 2025 09:35:49 -0400 Subject: [PATCH 31/33] Use IPV6_HDRINCL on Linux(#563) Instead of IP_HDRINCL in Socket:: set_header_included_v6. --- src/socket.rs | 3 +++ src/sys/unix.rs | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/socket.rs b/src/socket.rs index 1bed96f5..7f2a1edf 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1674,6 +1674,9 @@ impl Socket { setsockopt( self.as_raw(), sys::IPPROTO_IPV6, + #[cfg(target_os = "linux")] + sys::IPV6_HDRINCL, + #[cfg(not(target_os = "linux"))] sys::IP_HDRINCL, included as c_int, ) diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 37d0c3a6..8e24f4e5 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -124,6 +124,8 @@ pub(crate) use libc::SO_OOBINLINE; // Used in `Socket`. #[cfg(not(target_os = "nto"))] pub(crate) use libc::ipv6_mreq as Ipv6Mreq; +#[cfg(all(feature = "all", target_os = "linux"))] +pub(crate) use libc::IPV6_HDRINCL; #[cfg(all( feature = "all", not(any( From 33291e25b06d6af82ec05db988a7392fdf24f4da Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Tue, 18 Mar 2025 02:44:17 -0700 Subject: [PATCH 32/33] Enable `IP_BOUND_IF` on illumos and Solaris (#565) The `IP_BOUND_IF` socket option, which is wrapped by the `Socket::bind_device_by_index_{v4,v6}` and `Socket::device_index_{v4,v6}` is available on SunOS-like systems, such as illumos and Solaris, as well as macOS-like systems. However, these APIs are currently cfg-flagged to only be available on macOS-like systems. This commit changes the cfg attributes to also enable these APIs on illumos and Solaris. Fixes #560 Backport of 5c1f3b09897d251b8a10f690af71af13cc7d32ca From 36dec54c30c5ca0c711709b9e1f03b8cb8d155fa Mon Sep 17 00:00:00 2001 From: Boris N Date: Tue, 22 Apr 2025 11:26:03 +0200 Subject: [PATCH 33/33] Derive Copy and Clone for InterfaceIndexOrAddress Closes #570 --- src/socket.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/socket.rs b/src/socket.rs index 7f2a1edf..06cd07f9 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -809,7 +809,7 @@ fn set_common_flags(socket: Socket) -> io::Result { target_os = "redox", target_os = "solaris", )))] -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub enum InterfaceIndexOrAddress { /// An interface index. Index(u32),