@@ -164,7 +164,6 @@ fn test_so_tcp_maxseg() {
164
164
use nix:: sys:: socket:: {
165
165
accept, bind, connect, getsockname, listen, Backlog , SockaddrIn ,
166
166
} ;
167
- use nix:: unistd:: write;
168
167
use std:: net:: SocketAddrV4 ;
169
168
use std:: str:: FromStr ;
170
169
@@ -184,14 +183,12 @@ fn test_so_tcp_maxseg() {
184
183
let initial = getsockopt ( & rsock, sockopt:: TcpMaxSeg ) . unwrap ( ) ;
185
184
// Initial MSS is expected to be 536 (https://tools.ietf.org/html/rfc879#section-1) but some
186
185
// platforms keep it even lower. This might fail if you've tuned your initial MSS to be larger
187
- // than 700
186
+ // than `segsize`
187
+ let segsize: u32 = 873 ;
188
+ assert ! ( initial < segsize) ;
188
189
cfg_if ! {
189
190
if #[ cfg( linux_android) ] {
190
- let segsize: u32 = 873 ;
191
- assert!( initial < segsize) ;
192
191
setsockopt( & rsock, sockopt:: TcpMaxSeg , & segsize) . unwrap( ) ;
193
- } else {
194
- assert!( initial < 700 ) ;
195
192
}
196
193
}
197
194
@@ -203,20 +200,38 @@ fn test_so_tcp_maxseg() {
203
200
SockProtocol :: Tcp ,
204
201
)
205
202
. unwrap ( ) ;
203
+
206
204
connect ( ssock. as_raw_fd ( ) , & sock_addr) . unwrap ( ) ;
205
+
207
206
let rsess = accept ( rsock. as_raw_fd ( ) ) . unwrap ( ) ;
208
207
let rsess = unsafe { OwnedFd :: from_raw_fd ( rsess) } ;
209
- write ( & rsess, b"hello" ) . unwrap ( ) ;
210
- let actual = getsockopt ( & ssock, sockopt:: TcpMaxSeg ) . unwrap ( ) ;
211
- // Actual max segment size takes header lengths into account, max IPv4 options (60 bytes) + max
212
- // TCP options (40 bytes) are subtracted from the requested maximum as a lower boundary.
208
+
213
209
cfg_if ! {
214
- if #[ cfg( linux_android) ] {
215
- assert!( ( segsize - 100 ) <= actual) ;
216
- assert!( actual <= segsize) ;
210
+ if #[ cfg( apple_targets) ] {
211
+ // on apple targets (and unlike linux), we can only set the MSS on a *connected*
212
+ // socket. Also, the same MSS can't be read using getsockopt from the other end.
213
+
214
+ assert_ne!( segsize, getsockopt( & rsess, sockopt:: TcpMaxSeg ) . unwrap( ) ) ;
215
+ setsockopt( & rsess, sockopt:: TcpMaxSeg , & segsize) . unwrap( ) ;
216
+ assert_eq!( segsize, getsockopt( & rsess, sockopt:: TcpMaxSeg ) . unwrap( ) ) ;
217
+
218
+ assert_ne!( segsize, getsockopt( & ssock, sockopt:: TcpMaxSeg ) . unwrap( ) ) ;
219
+ setsockopt( & ssock, sockopt:: TcpMaxSeg , & segsize) . unwrap( ) ;
220
+ assert_eq!( segsize, getsockopt( & ssock, sockopt:: TcpMaxSeg ) . unwrap( ) ) ;
217
221
} else {
218
- assert!( initial < actual) ;
219
- assert!( 536 < actual) ;
222
+ use nix:: unistd:: write;
223
+
224
+ write( & rsess, b"hello" ) . unwrap( ) ;
225
+ let actual = getsockopt( & ssock, sockopt:: TcpMaxSeg ) . unwrap( ) ;
226
+ // Actual max segment size takes header lengths into account, max IPv4 options (60 bytes) + max
227
+ // TCP options (40 bytes) are subtracted from the requested maximum as a lower boundary.
228
+ if cfg!( linux_android) {
229
+ assert!( ( segsize - 100 ) <= actual) ;
230
+ assert!( actual <= segsize) ;
231
+ } else {
232
+ assert!( initial < actual) ;
233
+ assert!( 536 < actual) ;
234
+ }
220
235
}
221
236
}
222
237
}
0 commit comments