diff --git a/src/socket.rs b/src/socket.rs index 1afb50d9..c9945fe6 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1932,10 +1932,13 @@ impl Socket { /// /// [`set_only_v6`]: Socket::set_only_v6 pub fn only_v6(&self) -> io::Result { + #[cfg(not(windows))] unsafe { - getsockopt::(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_V6ONLY) + getsockopt::(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_V6ONLY) .map(|only_v6| only_v6 != 0) } + #[cfg(windows)] + sys::only_v6(self.as_raw()) } /// Set the value for the `IPV6_V6ONLY` option on this socket. diff --git a/src/sys/windows.rs b/src/sys/windows.rs index 33678bc2..5a2c89ff 100644 --- a/src/sys/windows.rs +++ b/src/sys/windows.rs @@ -892,6 +892,26 @@ pub(crate) fn to_mreqn( } } +pub(crate) fn only_v6(socket: RawSocket) -> io::Result { + let mut optval: c_int = 0; // input must be 4 bytes (DWORD) + let mut optlen = mem::size_of_val(&optval) as c_int; + syscall!( + getsockopt( + socket, + IPPROTO_IPV6 as i32, + IPV6_V6ONLY, + ptr::from_mut(&mut optval).cast(), + &mut optlen, + ), + PartialEq::eq, + SOCKET_ERROR + ) + .map(|_| { + // optlen may be 1, which won't match the input size of optval + optval != 0 + }) +} + #[cfg(feature = "all")] pub(crate) fn original_dst_v4(socket: RawSocket) -> io::Result { unsafe {