diff --git a/CHANGELOG.md b/CHANGELOG.md index 43d122ab10..e81f867a21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,9 @@ This project adheres to [Semantic Versioning](https://semver.org/). ([#1841](https://github.com/nix-rust/nix/pull/1841)) - Added `eaccess()` on FreeBSD, DragonFly and Linux (glibc and musl). ([#1842](https://github.com/nix-rust/nix/pull/1842)) - +- Added `IP_TOS` `SO_PRIORITY` and `IPV6_TCLASS` sockopts for Linux + ([#1853](https://github.com/nix-rust/nix/pull/1853)) + ### Changed - The MSRV is now 1.56.1 diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 90111ec54d..76289fd4aa 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -329,6 +329,26 @@ sockopt_impl!( /// Set or read a boolean integer argument that determines whether sent /// multicast packets should be looped back to the local sockets. IpMulticastLoop, Both, libc::IPPROTO_IP, libc::IP_MULTICAST_LOOP, bool); +#[cfg(target_os = "linux")] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Set the protocol-defined priority for all packets to be + /// sent on this socket + Priority, Both, libc::SOL_SOCKET, libc::SO_PRIORITY, libc::c_int); +#[cfg(target_os = "linux")] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Set or receive the Type-Of-Service (TOS) field that is + /// sent with every IP packet originating from this socket + IpTos, Both, libc::IPPROTO_IP, libc::IP_TOS, libc::c_int); +#[cfg(target_os = "linux")] +#[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Traffic class associated with outgoing packets + Ipv6TClass, Both, libc::IPPROTO_IPV6, libc::IPV6_TCLASS, libc::c_int); #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] #[cfg(feature = "net")] sockopt_impl!( diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index 2ddbf77b83..e6acfa5981 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -327,3 +327,51 @@ fn test_v6dontfrag_opts() { "unsetting IPV6_DONTFRAG on an inet6 datagram socket should succeed", ); } + +#[test] +#[cfg(target_os = "linux")] +fn test_so_priority() { + let fd = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + SockProtocol::Tcp, + ) + .unwrap(); + let priority = 3; + setsockopt(fd, sockopt::Priority, &priority).unwrap(); + assert_eq!(getsockopt(fd, sockopt::Priority).unwrap(), priority); +} + +#[test] +#[cfg(target_os = "linux")] +fn test_ip_tos() { + let fd = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + SockProtocol::Tcp, + ) + .unwrap(); + let tos = 0x80; // CS4 + setsockopt(fd, sockopt::IpTos, &tos).unwrap(); + assert_eq!(getsockopt(fd, sockopt::IpTos).unwrap(), tos); +} + +#[test] +#[cfg(target_os = "linux")] +// Disable the test under emulation because it fails in Cirrus-CI. Lack +// of QEMU support is suspected. +#[cfg_attr(qemu, ignore)] +fn test_ipv6_tclass() { + let fd = socket( + AddressFamily::Inet6, + SockType::Stream, + SockFlag::empty(), + SockProtocol::Tcp, + ) + .unwrap(); + let class = 0x80; // CS4 + setsockopt(fd, sockopt::Ipv6TClass, &class).unwrap(); + assert_eq!(getsockopt(fd, sockopt::Ipv6TClass).unwrap(), class); +}