summaryrefslogtreecommitdiff
path: root/test/sys
diff options
context:
space:
mode:
authoreaon <eaon@posteo.net>2021-08-25 15:27:33 -0400
committereaon <eaon@posteo.net>2021-09-04 22:39:55 -0400
commit76fe409f4b83573d3c706b530e4b0f937cc0b513 (patch)
treecd30f0eb4fae9a09c90b50774fe696959f0263e9 /test/sys
parentdab7332eabed8646f6d01a0d0688b4d1438accb4 (diff)
downloadnix-76fe409f4b83573d3c706b530e4b0f937cc0b513.zip
Support for `TCP_MAXSEG` TCP MSS socket option
Diffstat (limited to 'test/sys')
-rw-r--r--test/sys/test_sockopt.rs51
1 files changed, 51 insertions, 0 deletions
diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs
index 4d2d7e51..72c9a315 100644
--- a/test/sys/test_sockopt.rs
+++ b/test/sys/test_sockopt.rs
@@ -70,6 +70,57 @@ fn test_so_buf() {
assert!(actual >= bufsize);
}
+#[test]
+fn test_so_tcp_maxseg() {
+ use std::net::SocketAddr;
+ use std::str::FromStr;
+ use nix::sys::socket::{accept, bind, connect, listen, InetAddr, SockAddr};
+ use nix::unistd::{close, write};
+
+ let std_sa = SocketAddr::from_str("127.0.0.1:4001").unwrap();
+ let inet_addr = InetAddr::from_std(&std_sa);
+ let sock_addr = SockAddr::new_inet(inet_addr);
+
+ let rsock = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), SockProtocol::Tcp)
+ .unwrap();
+ bind(rsock, &sock_addr).unwrap();
+ listen(rsock, 10).unwrap();
+ let initial = getsockopt(rsock, sockopt::TcpMaxSeg).unwrap();
+ // Initial MSS is expected to be 536 (https://tools.ietf.org/html/rfc879#section-1) but some
+ // platforms keep it even lower. This might fail if you've tuned your initial MSS to be larger
+ // than 700
+ cfg_if! {
+ if #[cfg(any(target_os = "android", target_os = "linux"))] {
+ let segsize: u32 = 873;
+ assert!(initial < segsize);
+ setsockopt(rsock, sockopt::TcpMaxSeg, &segsize).unwrap();
+ } else {
+ assert!(initial < 700);
+ }
+ }
+
+ // Connect and check the MSS that was advertised
+ let ssock = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), SockProtocol::Tcp)
+ .unwrap();
+ connect(ssock, &sock_addr).unwrap();
+ let rsess = accept(rsock).unwrap();
+ write(rsess, b"hello").unwrap();
+ let actual = getsockopt(ssock, sockopt::TcpMaxSeg).unwrap();
+ // Actual max segment size takes header lengths into account, max IPv4 options (60 bytes) + max
+ // TCP options (40 bytes) are subtracted from the requested maximum as a lower boundary.
+ cfg_if! {
+ if #[cfg(any(target_os = "android", target_os = "linux"))] {
+ assert!((segsize - 100) <= actual);
+ assert!(actual <= segsize);
+ } else {
+ assert!(initial < actual);
+ assert!(536 < actual);
+ }
+ }
+ close(rsock).unwrap();
+ close(ssock).unwrap();
+}
+
// The CI doesn't supported getsockopt and setsockopt on emulated processors.
// It's beleived that a QEMU issue, the tests run ok on a fully emulated system.
// Current CI just run the binary with QEMU but the Kernel remains the same as the host.