mirror of
https://gitee.com/openharmony/third_party_rust_nix
synced 2025-01-05 23:09:03 +00:00
Support for TCP_MAXSEG
TCP MSS socket option
This commit is contained in:
parent
dab7332eab
commit
76fe409f4b
@ -30,6 +30,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
(#[1335](https://github.com/nix-rust/nix/pull/1335))
|
||||
- Exposed `SockAddr::from_raw_sockaddr`
|
||||
(#[1447](https://github.com/nix-rust/nix/pull/1447))
|
||||
- Added support for `TCP_MAXSEG` TCP Maximum Segment Size socket options
|
||||
(#[1292](https://github.com/nix-rust/nix/pull/1292))
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -265,6 +265,13 @@ sockopt_impl!(Both, TcpKeepAlive, libc::IPPROTO_TCP, libc::TCP_KEEPALIVE, u32);
|
||||
target_os = "linux",
|
||||
target_os = "nacl"))]
|
||||
sockopt_impl!(Both, TcpKeepIdle, libc::IPPROTO_TCP, libc::TCP_KEEPIDLE, u32);
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_os = "android", target_os = "linux"))] {
|
||||
sockopt_impl!(Both, TcpMaxSeg, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32);
|
||||
} else {
|
||||
sockopt_impl!(GetOnly, TcpMaxSeg, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32);
|
||||
}
|
||||
}
|
||||
#[cfg(not(target_os = "openbsd"))]
|
||||
sockopt_impl!(Both, TcpKeepCount, libc::IPPROTO_TCP, libc::TCP_KEEPCNT, u32);
|
||||
#[cfg(not(target_os = "openbsd"))]
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user