summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md4
-rw-r--r--src/sys/socket/sockopt.rs35
-rw-r--r--test/sys/test_sockopt.rs48
3 files changed, 86 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 10a95ad9..5294d286 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 e9f26333..08b73aaa 100644
--- a/src/sys/socket/sockopt.rs
+++ b/src/sys/socket/sockopt.rs
@@ -371,6 +371,41 @@ sockopt_impl!(
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 2ddbf77b..e6acfa59 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);
+}