diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c580fc893..267d18097d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). ([#1857](https://github.com/nix-rust/nix/pull/1857)) - Added `SockProtocol::Raw` for raw sockets ([#1848](https://github.com/nix-rust/nix/pull/1848)) +- added `IP_MTU` (`IpMtu`) `IPPROTO_IP` sockopt on Linux and Android. + ([#1865](https://github.com/nix-rust/nix/pull/1865)) ### Changed diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 08b73aaa81..7489858ee3 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -925,6 +925,15 @@ sockopt_impl!( libc::IPV6_RECVERR, bool ); +#[cfg(any(target_os = "android", target_os = "linux"))] +sockopt_impl!( + /// Fetch the current system-estimated Path MTU. + IpMtu, + GetOnly, + libc::IPPROTO_IP, + libc::IP_MTU, + libc::c_int +); #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] sockopt_impl!( /// Set or retrieve the current time-to-live field that is used in every diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index e6acfa5981..47b01c1605 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -236,6 +236,33 @@ fn test_so_tcp_keepalive() { } } +#[test] +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg_attr(qemu, ignore)] +fn test_get_mtu() { + use nix::sys::socket::{bind, connect, SockaddrIn}; + use std::net::SocketAddrV4; + use std::str::FromStr; + + let std_sa = SocketAddrV4::from_str("127.0.0.1:4001").unwrap(); + let std_sb = SocketAddrV4::from_str("127.0.0.1:4002").unwrap(); + + let usock = socket( + AddressFamily::Inet, + SockType::Datagram, + SockFlag::empty(), + SockProtocol::Udp, + ) + .unwrap(); + + // Bind and initiate connection + bind(usock, &SockaddrIn::from(std_sa)).unwrap(); + connect(usock, &SockaddrIn::from(std_sb)).unwrap(); + + // Loopback connections have 2^16 - the maximum - MTU + assert_eq!(getsockopt(usock, sockopt::IpMtu), Ok(u16::MAX as i32)) +} + #[test] #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] fn test_ttl_opts() {