diff --git a/changelog/2615.added.md b/changelog/2615.added.md new file mode 100644 index 0000000000..86080626c0 --- /dev/null +++ b/changelog/2615.added.md @@ -0,0 +1 @@ + Added `TCP_INFO` sockopt to read TCP socket information on _linux_. diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 11c3be9e13..08ae2cb1a4 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -1268,6 +1268,17 @@ sockopt_impl!( libc::SO_EXCLBIND, bool ); +#[cfg(target_os = "linux")] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Get tcp_info structure. + TcpInfo, + GetOnly, + libc::SOL_TCP, + libc::TCP_INFO, + libc::tcp_info +); #[allow(missing_docs)] // Not documented by Linux! diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index 42697ffa24..2dc304fba1 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -568,6 +568,23 @@ fn test_ipv6_tclass() { assert_eq!(getsockopt(&fd, sockopt::Ipv6TClass).unwrap(), class); } +#[test] +#[cfg(target_os = "linux")] +fn test_tcp_info() { + let fd = socket( + AddressFamily::Inet6, + SockType::Stream, + SockFlag::empty(), + SockProtocol::Tcp, + ) + .unwrap(); + let tcp_info = getsockopt(&fd, sockopt::TcpInfo).unwrap(); + // Silly assert for the sake of having one in the test. + // There should be no retransmits because nothing is sent through the + // socket in the first place. + assert_eq!(tcp_info.tcpi_retransmits, 0); +} + #[test] #[cfg(target_os = "freebsd")] fn test_receive_timestamp() {