diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c1f90ebff..4e3e2974c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,9 @@ This project adheres to [Semantic Versioning](https://semver.org/). (#[1670](https://github.com/nix-rust/nix/pull/1670)) - Added `waitid`. (#[1584](https://github.com/nix-rust/nix/pull/1584)) +- Added `Ipv6DontFrag` for android, iOS, linux and macOS. +- Added `IpDontFrag` for iOS, macOS. + (#[1692](https://github.com/nix-rust/nix/pull/1692)) ### Changed diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index c600391c64..e80b09e771 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -615,6 +615,19 @@ sockopt_impl!( sockopt_impl!( /// Set the unicast hop limit for the socket. Ipv6Ttl, Both, libc::IPPROTO_IPV6, libc::IPV6_UNICAST_HOPS, libc::c_int); +#[cfg(any(target_os = "ios", target_os = "macos"))] +sockopt_impl!( + /// Set "don't fragment packet" flag on the IP packet. + IpDontFrag, Both, libc::IPPROTO_IP, libc::IP_DONTFRAG, bool); +#[cfg(any( + target_os = "android", + target_os = "ios", + target_os = "linux", + target_os = "macos", +))] +sockopt_impl!( + /// Set "don't fragment packet" flag on the IPv6 packet. + Ipv6DontFrag, Both, libc::IPPROTO_IPV6, libc::IPV6_DONTFRAG, bool); #[allow(missing_docs)] // Not documented by Linux! diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index df01e9ee11..4f75e17846 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -196,3 +196,42 @@ fn test_ttl_opts() { setsockopt(fd6, sockopt::Ipv6Ttl, &1) .expect("setting ipv6ttl on an inet6 socket should succeed"); } + +#[test] +#[cfg(any(target_os = "ios", target_os = "macos"))] +fn test_dontfrag_opts() { + let fd4 = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), SockProtocol::Tcp).unwrap(); + setsockopt(fd4, sockopt::IpDontFrag, &true) + .expect("setting IP_DONTFRAG on an inet stream socket should succeed"); + setsockopt(fd4, sockopt::IpDontFrag, &false) + .expect("unsetting IP_DONTFRAG on an inet stream socket should succeed"); + let fd4d = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None).unwrap(); + setsockopt(fd4d, sockopt::IpDontFrag, &true) + .expect("setting IP_DONTFRAG on an inet datagram socket should succeed"); + setsockopt(fd4d, sockopt::IpDontFrag, &false) + .expect("unsetting IP_DONTFRAG on an inet datagram socket should succeed"); +} + +#[test] +#[cfg(any( + target_os = "android", + target_os = "ios", + target_os = "linux", + target_os = "macos", + ) +)] +// Disable the test under emulation because it fails in Cirrus-CI. Lack +// of QEMU support is suspected. +#[cfg_attr(qemu, ignore)] +fn test_v6dontfrag_opts() { + let fd6 = socket(AddressFamily::Inet6, SockType::Stream, SockFlag::empty(), SockProtocol::Tcp).unwrap(); + setsockopt(fd6, sockopt::Ipv6DontFrag, &true) + .expect("setting IPV6_DONTFRAG on an inet6 stream socket should succeed"); + setsockopt(fd6, sockopt::Ipv6DontFrag, &false) + .expect("unsetting IPV6_DONTFRAG on an inet6 stream socket should succeed"); + let fd6d = socket(AddressFamily::Inet6, SockType::Datagram, SockFlag::empty(), None).unwrap(); + setsockopt(fd6d, sockopt::Ipv6DontFrag, &true) + .expect("setting IPV6_DONTFRAG on an inet6 datagram socket should succeed"); + setsockopt(fd6d, sockopt::Ipv6DontFrag, &false) + .expect("unsetting IPV6_DONTFRAG on an inet6 datagram socket should succeed"); +}