@@ -163,7 +163,6 @@ fn test_so_tcp_maxseg() {
163
163
use nix:: sys:: socket:: {
164
164
accept, bind, connect, getsockname, listen, Backlog , SockaddrIn ,
165
165
} ;
166
- use nix:: unistd:: write;
167
166
use std:: net:: SocketAddrV4 ;
168
167
use std:: str:: FromStr ;
169
168
@@ -183,14 +182,12 @@ fn test_so_tcp_maxseg() {
183
182
let initial = getsockopt ( & rsock, sockopt:: TcpMaxSeg ) . unwrap ( ) ;
184
183
// Initial MSS is expected to be 536 (https://tools.ietf.org/html/rfc879#section-1) but some
185
184
// 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) ;
187
188
cfg_if ! {
188
189
if #[ cfg( linux_android) ] {
189
- let segsize: u32 = 873 ;
190
- assert!( initial < segsize) ;
191
190
setsockopt( & rsock, sockopt:: TcpMaxSeg , & segsize) . unwrap( ) ;
192
- } else {
193
- assert!( initial < 700 ) ;
194
191
}
195
192
}
196
193
@@ -202,20 +199,38 @@ fn test_so_tcp_maxseg() {
202
199
SockProtocol :: Tcp ,
203
200
)
204
201
. unwrap ( ) ;
202
+
205
203
connect ( ssock. as_raw_fd ( ) , & sock_addr) . unwrap ( ) ;
204
+
206
205
let rsess = accept ( rsock. as_raw_fd ( ) ) . unwrap ( ) ;
207
206
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
+
212
208
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( ) ) ;
216
220
} 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
+ }
219
234
}
220
235
}
221
236
}
0 commit comments