diff --git a/src/socket.rs b/src/socket.rs index 1fc6f080..d0378821 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1167,7 +1167,7 @@ const fn into_linger(duration: Option) -> sys::linger { } } -/// Socket options for IPv4 sockets, get/set using `IPPROTO_IP`. +/// Socket options for IPv4 sockets, get/set using `IPPROTO_IP` or `SOL_IP`. /// /// Additional documentation can be found in documentation of the OS. /// * Linux: @@ -1670,9 +1670,23 @@ impl Socket { .map(|recv_tos| recv_tos > 0) } } + + /// 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", + ) + ))] + pub fn original_dst_v4(&self) -> io::Result { + sys::original_dst_v4(self.as_raw()) + } } -/// Socket options for IPv6 sockets, get/set using `IPPROTO_IPV6`. +/// Socket options for IPv6 sockets, get/set using `IPPROTO_IPV6` or `SOL_IPV6`. /// /// Additional documentation can be found in documentation of the OS. /// * Linux: @@ -2075,6 +2089,15 @@ impl Socket { ) } } + + /// 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") + ))] + pub fn original_dst_v6(&self) -> io::Result { + sys::original_dst_v6(self.as_raw()) + } } /// Socket options for TCP sockets, get/set using `IPPROTO_TCP`. @@ -2096,8 +2119,8 @@ impl Socket { target_os = "vita" )) ))] - pub fn keepalive_time(&self) -> io::Result { - sys::keepalive_time(self.as_raw()) + pub fn tcp_keepalive_time(&self) -> io::Result { + sys::tcp_keepalive_time(self.as_raw()) } /// Get the value of the `TCP_KEEPINTVL` option on this socket. @@ -2123,7 +2146,7 @@ impl Socket { target_os = "cygwin", ) ))] - pub fn keepalive_interval(&self) -> io::Result { + pub fn tcp_keepalive_interval(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_TCP, sys::TCP_KEEPINTVL) .map(|secs| Duration::from_secs(secs as u64)) @@ -2154,7 +2177,7 @@ impl Socket { target_os = "windows", ) ))] - pub fn keepalive_retries(&self) -> io::Result { + pub fn tcp_keepalive_retries(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_TCP, sys::TCP_KEEPCNT) .map(|retries| retries as u32) @@ -2206,10 +2229,10 @@ impl Socket { /// Get the value of the `TCP_NODELAY` option on this socket. /// - /// For more information about this option, see [`set_nodelay`]. + /// For more information about this option, see [`set_tcp_nodelay`]. /// - /// [`set_nodelay`]: Socket::set_nodelay - pub fn nodelay(&self) -> io::Result { + /// [`set_tcp_nodelay`]: Socket::set_tcp_nodelay + pub fn tcp_nodelay(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), sys::IPPROTO_TCP, sys::TCP_NODELAY) .map(|nodelay| nodelay != 0) @@ -2223,7 +2246,7 @@ impl Socket { /// small amount of data. When not set, data is buffered until there is a /// sufficient amount to send out, thereby avoiding the frequent sending of /// small packets. - pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { + pub fn set_tcp_nodelay(&self, nodelay: bool) -> io::Result<()> { unsafe { setsockopt( self.as_raw(), @@ -2233,29 +2256,6 @@ 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", - ) - ))] - 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") - ))] - pub fn original_dst_ipv6(&self) -> io::Result { - sys::original_dst_ipv6(self.as_raw()) - } } impl Read for Socket { diff --git a/src/sockref.rs b/src/sockref.rs index 59353b15..2a9f245f 100644 --- a/src/sockref.rs +++ b/src/sockref.rs @@ -49,8 +49,8 @@ use crate::Socket; /// /// // Create a `SockRef`erence to the stream. /// let socket_ref = SockRef::from(&stream); -/// // Use `Socket::set_nodelay` on the stream. -/// socket_ref.set_nodelay(true)?; +/// // Use `Socket::set_tcp_nodelay` on the stream. +/// socket_ref.set_tcp_nodelay(true)?; /// drop(socket_ref); /// /// assert_eq!(stream.nodelay()?, true); diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 0421bf88..e3ec1da7 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -1187,7 +1187,7 @@ fn into_timeval(duration: Option) -> libc::timeval { feature = "all", not(any(target_os = "haiku", target_os = "openbsd", target_os = "vita")) ))] -pub(crate) fn keepalive_time(fd: Socket) -> io::Result { +pub(crate) fn tcp_keepalive_time(fd: Socket) -> io::Result { unsafe { getsockopt::(fd, IPPROTO_TCP, KEEPALIVE_TIME) .map(|secs| Duration::from_secs(secs as u64)) @@ -1380,7 +1380,7 @@ pub(crate) const fn to_mreqn( feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))] -pub(crate) fn original_dst(fd: Socket) -> io::Result { +pub(crate) fn original_dst_v4(fd: Socket) -> io::Result { // Safety: `getsockopt` initialises the `SockAddr` for us. unsafe { SockAddr::try_init(|storage, len| { @@ -1401,7 +1401,7 @@ pub(crate) fn original_dst(fd: Socket) -> io::Result { /// 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 { +pub(crate) fn original_dst_v6(fd: Socket) -> io::Result { // Safety: `getsockopt` initialises the `SockAddr` for us. unsafe { SockAddr::try_init(|storage, len| { @@ -1565,11 +1565,11 @@ impl crate::Socket { /// Gets the value of the `TCP_MAXSEG` option on this socket. /// - /// For more information about this option, see [`set_mss`]. + /// For more information about this option, see [`set_tcp_mss`]. /// - /// [`set_mss`]: crate::Socket::set_mss + /// [`set_tcp_mss`]: crate::Socket::set_tcp_mss #[cfg(all(feature = "all", not(target_os = "redox")))] - pub fn mss(&self) -> io::Result { + pub fn tcp_mss(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::IPPROTO_TCP, libc::TCP_MAXSEG) .map(|mss| mss as u32) @@ -1581,7 +1581,7 @@ 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")))] - pub fn set_mss(&self, mss: u32) -> io::Result<()> { + pub fn set_tcp_mss(&self, mss: u32) -> io::Result<()> { unsafe { setsockopt( self.as_raw(), @@ -1690,14 +1690,14 @@ impl crate::Socket { /// Get the value of the `TCP_CORK` option on this socket. /// - /// For more information about this option, see [`set_cork`]. + /// For more information about this option, see [`set_tcp_cork`]. /// - /// [`set_cork`]: crate::Socket::set_cork + /// [`set_tcp_cork`]: crate::Socket::set_tcp_cork #[cfg(all( feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))] - pub fn cork(&self) -> io::Result { + pub fn tcp_cork(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::IPPROTO_TCP, libc::TCP_CORK) .map(|cork| cork != 0) @@ -1714,7 +1714,7 @@ impl crate::Socket { feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))] - pub fn set_cork(&self, cork: bool) -> io::Result<()> { + pub fn set_tcp_cork(&self, cork: bool) -> io::Result<()> { unsafe { setsockopt( self.as_raw(), @@ -1727,9 +1727,9 @@ impl crate::Socket { /// Get the value of the `TCP_QUICKACK` option on this socket. /// - /// For more information about this option, see [`set_quickack`]. + /// For more information about this option, see [`set_tcp_quickack`]. /// - /// [`set_quickack`]: crate::Socket::set_quickack + /// [`set_tcp_quickack`]: crate::Socket::set_tcp_quickack #[cfg(all( feature = "all", any( @@ -1739,7 +1739,7 @@ impl crate::Socket { target_os = "cygwin", ) ))] - pub fn quickack(&self) -> io::Result { + pub fn tcp_quickack(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::IPPROTO_TCP, libc::TCP_QUICKACK) .map(|quickack| quickack != 0) @@ -1761,7 +1761,7 @@ impl crate::Socket { target_os = "cygwin", ) ))] - pub fn set_quickack(&self, quickack: bool) -> io::Result<()> { + pub fn set_tcp_quickack(&self, quickack: bool) -> io::Result<()> { unsafe { setsockopt( self.as_raw(), @@ -1774,14 +1774,14 @@ impl crate::Socket { /// Get the value of the `TCP_THIN_LINEAR_TIMEOUTS` option on this socket. /// - /// For more information about this option, see [`set_thin_linear_timeouts`]. + /// For more information about this option, see [`set_tcp_thin_linear_timeouts`]. /// - /// [`set_thin_linear_timeouts`]: crate::Socket::set_thin_linear_timeouts + /// [`set_tcp_thin_linear_timeouts`]: crate::Socket::set_tcp_thin_linear_timeouts #[cfg(all( feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))] - pub fn thin_linear_timeouts(&self) -> io::Result { + pub fn tcp_thin_linear_timeouts(&self) -> io::Result { unsafe { getsockopt::( self.as_raw(), @@ -1801,7 +1801,7 @@ impl crate::Socket { feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))] - pub fn set_thin_linear_timeouts(&self, timeouts: bool) -> io::Result<()> { + pub fn set_tcp_thin_linear_timeouts(&self, timeouts: bool) -> io::Result<()> { unsafe { setsockopt( self.as_raw(), @@ -2160,14 +2160,14 @@ impl crate::Socket { /// Get the value of the `IP_FREEBIND` option on this socket. /// - /// For more information about this option, see [`set_freebind`]. + /// For more information about this option, see [`set_freebind_v4`]. /// - /// [`set_freebind`]: crate::Socket::set_freebind + /// [`set_freebind_v4`]: crate::Socket::set_freebind_v4 #[cfg(all( feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))] - pub fn freebind(&self) -> io::Result { + pub fn freebind_v4(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::SOL_IP, libc::IP_FREEBIND) .map(|freebind| freebind != 0) @@ -2185,7 +2185,7 @@ impl crate::Socket { feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))] - pub fn set_freebind(&self, freebind: bool) -> io::Result<()> { + pub fn set_freebind_v4(&self, freebind: bool) -> io::Result<()> { unsafe { setsockopt( self.as_raw(), @@ -2200,11 +2200,11 @@ impl crate::Socket { /// /// This is an IPv6 counterpart of `IP_FREEBIND` socket option on /// Android/Linux. For more information about this option, see - /// [`set_freebind`]. + /// [`set_freebind_v4`]. /// - /// [`set_freebind`]: crate::Socket::set_freebind + /// [`set_freebind_v4`]: crate::Socket::set_freebind_v4 #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] - pub fn freebind_ipv6(&self) -> io::Result { + pub fn freebind_v6(&self) -> io::Result { unsafe { getsockopt::(self.as_raw(), libc::SOL_IPV6, libc::IPV6_FREEBIND) .map(|freebind| freebind != 0) @@ -2215,9 +2215,9 @@ impl crate::Socket { /// /// This is an IPv6 counterpart of `IP_FREEBIND` socket option on /// Android/Linux. For more information about this option, see - /// [`set_freebind`]. + /// [`set_freebind_v4`]. /// - /// [`set_freebind`]: crate::Socket::set_freebind + /// [`set_freebind_v4`]: crate::Socket::set_freebind_v4 /// /// # Examples /// @@ -2229,8 +2229,8 @@ impl crate::Socket { /// /// fn enable_freebind(socket: &Socket) -> io::Result<()> { /// match socket.domain()? { - /// Domain::IPV4 => socket.set_freebind(true)?, - /// Domain::IPV6 => socket.set_freebind_ipv6(true)?, + /// Domain::IPV4 => socket.set_freebind_v4(true)?, + /// Domain::IPV6 => socket.set_freebind_v6(true)?, /// _ => return Err(Error::new(ErrorKind::Other, "unsupported domain")), /// }; /// Ok(()) @@ -2242,7 +2242,7 @@ impl crate::Socket { /// # } /// ``` #[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))] - pub fn set_freebind_ipv6(&self, freebind: bool) -> io::Result<()> { + pub fn set_freebind_v6(&self, freebind: bool) -> io::Result<()> { unsafe { setsockopt( self.as_raw(), diff --git a/src/sys/windows.rs b/src/sys/windows.rs index 3a487205..9918eeb5 100644 --- a/src/sys/windows.rs +++ b/src/sys/windows.rs @@ -883,7 +883,7 @@ pub(crate) fn to_mreqn( } #[cfg(feature = "all")] -pub(crate) fn original_dst(socket: Socket) -> io::Result { +pub(crate) fn original_dst_v4(socket: Socket) -> io::Result { unsafe { SockAddr::try_init(|storage, len| { syscall!( @@ -903,7 +903,7 @@ pub(crate) fn original_dst(socket: Socket) -> io::Result { } #[cfg(feature = "all")] -pub(crate) fn original_dst_ipv6(socket: Socket) -> io::Result { +pub(crate) fn original_dst_v6(socket: Socket) -> io::Result { unsafe { SockAddr::try_init(|storage, len| { syscall!( diff --git a/tests/socket.rs b/tests/socket.rs index 05ba1fe3..a019b555 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -912,7 +912,10 @@ fn tcp_keepalive() { feature = "all", not(any(windows, target_os = "haiku", target_os = "openbsd")) ))] - assert_eq!(socket.keepalive_time().unwrap(), Duration::from_secs(200)); + assert_eq!( + socket.tcp_keepalive_time().unwrap(), + Duration::from_secs(200) + ); #[cfg(all( feature = "all", @@ -932,7 +935,7 @@ fn tcp_keepalive() { ) ))] assert_eq!( - socket.keepalive_interval().unwrap(), + socket.tcp_keepalive_interval().unwrap(), Duration::from_secs(30) ); @@ -954,7 +957,7 @@ fn tcp_keepalive() { target_os = "windows", ) ))] - assert_eq!(socket.keepalive_retries().unwrap(), 10); + assert_eq!(socket.tcp_keepalive_retries().unwrap(), 10); } #[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))] @@ -1350,7 +1353,7 @@ const GET_BUF_SIZE: usize = SET_BUF_SIZE; #[cfg(target_os = "linux")] const GET_BUF_SIZE: usize = 2 * SET_BUF_SIZE; -test!(nodelay, set_nodelay(true)); +test!(tcp_nodelay, set_tcp_nodelay(true)); test!( recv_buffer_size, set_recv_buffer_size(SET_BUF_SIZE), @@ -1383,8 +1386,8 @@ test!(reuse_port_lb, set_reuse_port_lb(true)); ))] test!( #[cfg_attr(target_os = "linux", ignore = "Different value returned")] - mss, - set_mss(256) + tcp_mss, + set_tcp_mss(256) ); #[cfg(all(feature = "all", target_os = "linux"))] test!( @@ -1402,17 +1405,17 @@ test!( feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))] -test!(cork, set_cork(true)); +test!(tcp_cork, set_tcp_cork(true)); #[cfg(all( feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))] -test!(quickack, set_quickack(false)); +test!(tcp_quickack, set_tcp_quickack(false)); #[cfg(all( feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))] -test!(thin_linear_timeouts, set_thin_linear_timeouts(true)); +test!(tcp_thin_linear_timeouts, set_tcp_thin_linear_timeouts(true)); test!(linger, set_linger(Some(Duration::from_secs(10)))); test!( read_timeout, @@ -1420,9 +1423,9 @@ test!( ); test!(keepalive, set_keepalive(true)); #[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))] -test!(freebind, set_freebind(true)); +test!(freebind_v4, set_freebind_v4(true)); #[cfg(all(feature = "all", target_os = "linux"))] -test!(IPv6 freebind_ipv6, set_freebind_ipv6(true)); +test!(IPv6 freebind_v6, set_freebind_v6(true)); test!(IPv4 ttl_v4, set_ttl_v4(40)); @@ -1654,21 +1657,21 @@ fn header_included_ipv6() { target_os = "windows" ) ))] -fn original_dst() { +fn original_dst_v4() { 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"), + match socket.original_dst_v4() { + Ok(_) => panic!("original_dst_v4 on non-redirected socket should fail"), 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"), + match socket.original_dst_v4() { + Ok(_) => panic!("original_dst_v4 on non-redirected socket should fail"), Err(err) => assert_eq!(err.raw_os_error(), expected), } } @@ -1678,7 +1681,7 @@ fn original_dst() { feature = "all", any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))] -fn original_dst_ipv6() { +fn original_dst_v6() { let socket = Socket::new(Domain::IPV6, Type::STREAM, None).unwrap(); #[cfg(not(target_os = "windows"))] let expected = Some(libc::ENOENT); @@ -1688,15 +1691,15 @@ fn original_dst_ipv6() { 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"), + match socket.original_dst_v6() { + Ok(_) => panic!("original_dst_v6 on non-redirected socket should fail"), 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"), + match socket.original_dst_v6() { + Ok(_) => panic!("original_dst_v6 on non-redirected socket should fail"), Err(err) => assert_eq!(err.raw_os_error(), expected_v4), } }