Skip to content

Commit 4565854

Browse files
committed
Enable TcpMaxSeg socket option for apple targets
1 parent 003bfe4 commit 4565854

File tree

3 files changed

+32
-16
lines changed

3 files changed

+32
-16
lines changed

changelog/2603.added.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added the TcpMaxSeg `setsockopt` option for apple targets

src/sys/socket/sockopt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ sockopt_impl!(
698698
u32
699699
);
700700
cfg_if! {
701-
if #[cfg(linux_android)] {
701+
if #[cfg(any(linux_android, apple_targets))] {
702702
sockopt_impl!(
703703
/// The maximum segment size for outgoing TCP packets.
704704
TcpMaxSeg, Both, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32);

test/sys/test_sockopt.rs

+30-15
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ fn test_so_tcp_maxseg() {
163163
use nix::sys::socket::{
164164
accept, bind, connect, getsockname, listen, Backlog, SockaddrIn,
165165
};
166-
use nix::unistd::write;
167166
use std::net::SocketAddrV4;
168167
use std::str::FromStr;
169168

@@ -183,14 +182,12 @@ fn test_so_tcp_maxseg() {
183182
let initial = getsockopt(&rsock, sockopt::TcpMaxSeg).unwrap();
184183
// Initial MSS is expected to be 536 (https://tools.ietf.org/html/rfc879#section-1) but some
185184
// platforms keep it even lower. This might fail if you've tuned your initial MSS to be larger
186-
// than 700
185+
// than `segsize`
186+
let segsize: u32 = 873;
187+
assert!(initial < segsize);
187188
cfg_if! {
188189
if #[cfg(linux_android)] {
189-
let segsize: u32 = 873;
190-
assert!(initial < segsize);
191190
setsockopt(&rsock, sockopt::TcpMaxSeg, &segsize).unwrap();
192-
} else {
193-
assert!(initial < 700);
194191
}
195192
}
196193

@@ -202,20 +199,38 @@ fn test_so_tcp_maxseg() {
202199
SockProtocol::Tcp,
203200
)
204201
.unwrap();
202+
205203
connect(ssock.as_raw_fd(), &sock_addr).unwrap();
204+
206205
let rsess = accept(rsock.as_raw_fd()).unwrap();
207206
let rsess = unsafe { OwnedFd::from_raw_fd(rsess) };
208-
write(&rsess, b"hello").unwrap();
209-
let actual = getsockopt(&ssock, sockopt::TcpMaxSeg).unwrap();
210-
// Actual max segment size takes header lengths into account, max IPv4 options (60 bytes) + max
211-
// TCP options (40 bytes) are subtracted from the requested maximum as a lower boundary.
207+
212208
cfg_if! {
213-
if #[cfg(linux_android)] {
214-
assert!((segsize - 100) <= actual);
215-
assert!(actual <= segsize);
209+
if #[cfg(apple_targets)] {
210+
// on apple targets (and unlike linux), we can only set the MSS on a *connected*
211+
// socket. Also, the same MSS can't be read using getsockopt from the other end.
212+
213+
assert_ne!(segsize, getsockopt(&rsess, sockopt::TcpMaxSeg).unwrap());
214+
setsockopt(&rsess, sockopt::TcpMaxSeg, &segsize).unwrap();
215+
assert_eq!(segsize, getsockopt(&rsess, sockopt::TcpMaxSeg).unwrap());
216+
217+
assert_ne!(segsize, getsockopt(&ssock, sockopt::TcpMaxSeg).unwrap());
218+
setsockopt(&ssock, sockopt::TcpMaxSeg, &segsize).unwrap();
219+
assert_eq!(segsize, getsockopt(&ssock, sockopt::TcpMaxSeg).unwrap());
216220
} else {
217-
assert!(initial < actual);
218-
assert!(536 < actual);
221+
use nix::unistd::write;
222+
223+
write(&rsess, b"hello").unwrap();
224+
let actual = getsockopt(&ssock, sockopt::TcpMaxSeg).unwrap();
225+
// Actual max segment size takes header lengths into account, max IPv4 options (60 bytes) + max
226+
// TCP options (40 bytes) are subtracted from the requested maximum as a lower boundary.
227+
if cfg!(linux_android) {
228+
assert!((segsize - 100) <= actual);
229+
assert!(actual <= segsize);
230+
} else {
231+
assert!(initial < actual);
232+
assert!(536 < actual);
233+
}
219234
}
220235
}
221236
}

0 commit comments

Comments
 (0)