mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Return user_mss if user_mss is set and socket is unconnected.
Has the same effect as Linux commit 34dfde4ad87b ("tcp: Return user_mss for
TCP_MAXSEG in CLOSE/LISTEN state if user_mss set").
Updated test to accept both values (default and user set) so test works on
newer and older kernels.
PiperOrigin-RevId: 563844012
This commit is contained in:
@@ -2059,11 +2059,16 @@ func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, tcpip.Error) {
|
||||
return v, nil
|
||||
|
||||
case tcpip.MaxSegOption:
|
||||
// This is just stubbed out. Linux never returns the user_mss
|
||||
// value as it either returns the defaultMSS or returns the
|
||||
// actual current MSS. Netstack just returns the defaultMSS
|
||||
// always for now.
|
||||
// Linux only returns user_mss value if user_mss is set and the socket is
|
||||
// unconnected. Otherwise Linux returns the actual current MSS. Netstack
|
||||
// mimics the user_mss behavior, but otherwise just returns the defaultMSS
|
||||
// for now.
|
||||
v := header.TCPDefaultMSS
|
||||
e.LockUser()
|
||||
if state := e.EndpointState(); e.userMSS > 0 && (state.internal() || state == StateClose || state == StateListen) {
|
||||
v = int(e.userMSS)
|
||||
}
|
||||
e.UnlockUser()
|
||||
return v, nil
|
||||
|
||||
case tcpip.MTUDiscoverOption:
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/time/clock.h"
|
||||
@@ -38,6 +39,8 @@
|
||||
#include "test/util/test_util.h"
|
||||
#include "test/util/thread_util.h"
|
||||
|
||||
using ::testing::AnyOf;
|
||||
|
||||
namespace gvisor {
|
||||
namespace testing {
|
||||
|
||||
@@ -1857,17 +1860,19 @@ TEST_P(SimpleTcpSocketTest, SetMaxSeg) {
|
||||
sizeof(kTCPMaxSeg)),
|
||||
SyscallSucceedsWithValue(0));
|
||||
|
||||
// Linux actually never returns the user_mss value. It will always return the
|
||||
// default MSS value defined above for an unconnected socket and always return
|
||||
// the actual current MSS for a connected one.
|
||||
int optval;
|
||||
socklen_t optlen = sizeof(optval);
|
||||
ASSERT_THAT(getsockopt(s.get(), IPPROTO_TCP, TCP_MAXSEG, &optval, &optlen),
|
||||
SyscallSucceedsWithValue(0));
|
||||
ASSERT_EQ(optlen, sizeof(optval));
|
||||
|
||||
EXPECT_EQ(kDefaultMSS, optval);
|
||||
EXPECT_EQ(sizeof(optval), optlen);
|
||||
// In older Linux versions, user_mss value was never actually returned. Linux
|
||||
// would always return the default MSS value for an unconnected socket and
|
||||
// always return the actual current MSS for a connected one. However, the
|
||||
// behavior changed since 34dfde4ad87b ("tcp: Return user_mss for TCP_MAXSEG
|
||||
// in CLOSE/LISTEN state if user_mss set"). With this change, user_mss is
|
||||
// returned if set for unconnected sockets. So allow both.
|
||||
EXPECT_THAT(optval, AnyOf(kDefaultMSS, kTCPMaxSeg));
|
||||
}
|
||||
|
||||
TEST_P(SimpleTcpSocketTest, SetMaxSegFailsForInvalidMSSValues) {
|
||||
|
||||
Reference in New Issue
Block a user