diff options
author | Kevin Krakauer <krakauer@google.com> | 2021-07-15 15:32:22 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-07-15 15:34:34 -0700 |
commit | cd45d7b6c893aa763cdc3ef2f4ac86444b622927 (patch) | |
tree | 64f2b18f3d9fa7ab4f0e5c0b3ac6b58b4f731b1d /test/syscalls/linux | |
parent | 67d9050752ca99f1194ecd31bc2dfce470a404aa (diff) |
netstack: support SO_RCVBUFFORCE
TCP is fully supported. As with SO_RCVBUF, other transport protocols perform
no-ops per DefaultSocketOptionsHandler.OnSetReceiveBufferSize.
PiperOrigin-RevId: 385023239
Diffstat (limited to 'test/syscalls/linux')
-rw-r--r-- | test/syscalls/linux/BUILD | 1 | ||||
-rw-r--r-- | test/syscalls/linux/socket_generic_test_cases.cc | 44 |
2 files changed, 45 insertions, 0 deletions
diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 984122bb5..fa2a080f1 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -2395,6 +2395,7 @@ cc_library( "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", gtest, + "//test/util:capability_util", "//test/util:test_util", ], alwayslink = 1, diff --git a/test/syscalls/linux/socket_generic_test_cases.cc b/test/syscalls/linux/socket_generic_test_cases.cc index 5c4cb6c35..fe5171bc8 100644 --- a/test/syscalls/linux/socket_generic_test_cases.cc +++ b/test/syscalls/linux/socket_generic_test_cases.cc @@ -14,6 +14,9 @@ #include "test/syscalls/linux/socket_generic.h" +#ifdef __linux__ +#include <linux/capability.h> +#endif // __linux__ #include <stdio.h> #include <sys/ioctl.h> #include <sys/socket.h> @@ -24,6 +27,7 @@ #include "absl/strings/string_view.h" #include "test/syscalls/linux/socket_test_util.h" #include "test/syscalls/linux/unix_domain_socket_test_util.h" +#include "test/util/capability_util.h" #include "test/util/test_util.h" // This file is a generic socket test file. It must be built with another file @@ -400,6 +404,46 @@ TEST_P(AllSocketPairTest, RcvBufSucceeds) { EXPECT_GT(size, 0); } +#ifdef __linux__ + +// Check that setting SO_RCVBUFFORCE above max is not clamped to the maximum +// receive buffer size. +TEST_P(AllSocketPairTest, SetSocketRecvBufForceAboveMax) { + std::unique_ptr<SocketPair> sockets = + ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + // Discover maxmimum buffer size by setting to a really large value. + constexpr int kRcvBufSz = 0xffffffff; + ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVBUF, &kRcvBufSz, + sizeof(kRcvBufSz)), + SyscallSucceeds()); + + int max = 0; + socklen_t max_len = sizeof(max); + ASSERT_THAT( + getsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVBUF, &max, &max_len), + SyscallSucceeds()); + + int above_max = max + 1; + int sso = setsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVBUFFORCE, + &above_max, sizeof(above_max)); + if (!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN))) { + ASSERT_THAT(sso, SyscallFailsWithErrno(EPERM)); + return; + } + ASSERT_THAT(sso, SyscallSucceeds()); + + int val = 0; + socklen_t val_len = sizeof(val); + ASSERT_THAT( + getsockopt(sockets->first_fd(), SOL_SOCKET, SO_RCVBUF, &val, &val_len), + SyscallSucceeds()); + // The system doubles the passed-in maximum. + ASSERT_EQ(above_max * 2, val); +} + +#endif // __linux__ + TEST_P(AllSocketPairTest, GetSndBufSucceeds) { auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); int size = 0; |