summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls/linux
diff options
context:
space:
mode:
Diffstat (limited to 'test/syscalls/linux')
-rw-r--r--test/syscalls/linux/packet_socket_raw.cc52
-rw-r--r--test/syscalls/linux/socket_test_util.cc13
-rw-r--r--test/syscalls/linux/socket_test_util.h7
3 files changed, 71 insertions, 1 deletions
diff --git a/test/syscalls/linux/packet_socket_raw.cc b/test/syscalls/linux/packet_socket_raw.cc
index a7c46adbf..2ed4f6f9c 100644
--- a/test/syscalls/linux/packet_socket_raw.cc
+++ b/test/syscalls/linux/packet_socket_raw.cc
@@ -678,6 +678,58 @@ TEST_P(RawPacketTest, GetSocketAcceptConn) {
INSTANTIATE_TEST_SUITE_P(AllInetTests, RawPacketTest,
::testing::Values(ETH_P_IP, ETH_P_ALL));
+class RawPacketMsgSizeTest : public ::testing::TestWithParam<TestAddress> {};
+
+TEST_P(RawPacketMsgSizeTest, SendTooLong) {
+ SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW)));
+
+ TestAddress addr = GetParam().WithPort(kPort);
+
+ FileDescriptor udp_sock =
+ ASSERT_NO_ERRNO_AND_VALUE(Socket(addr.family(), SOCK_RAW, IPPROTO_UDP));
+
+ ASSERT_THAT(
+ connect(udp_sock.get(), reinterpret_cast<struct sockaddr*>(&addr.addr),
+ addr.addr_len),
+ SyscallSucceeds());
+
+ const char buf[65536] = {};
+ ASSERT_THAT(send(udp_sock.get(), buf, sizeof(buf), 0),
+ SyscallFailsWithErrno(EMSGSIZE));
+}
+
+TEST_P(RawPacketMsgSizeTest, SpliceTooLong) {
+ SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW)));
+
+ const char buf[65536] = {};
+ int fds[2];
+ ASSERT_THAT(pipe(fds), SyscallSucceeds());
+ ASSERT_THAT(write(fds[1], buf, sizeof(buf)),
+ SyscallSucceedsWithValue(sizeof(buf)));
+
+ TestAddress addr = GetParam().WithPort(kPort);
+
+ FileDescriptor udp_sock =
+ ASSERT_NO_ERRNO_AND_VALUE(Socket(addr.family(), SOCK_RAW, IPPROTO_UDP));
+
+ ASSERT_THAT(
+ connect(udp_sock.get(), reinterpret_cast<struct sockaddr*>(&addr.addr),
+ addr.addr_len),
+ SyscallSucceeds());
+
+ ssize_t n = splice(fds[0], nullptr, udp_sock.get(), nullptr, sizeof(buf), 0);
+ if (IsRunningOnGvisor()) {
+ EXPECT_THAT(n, SyscallFailsWithErrno(EMSGSIZE));
+ } else {
+ // TODO(gvisor.dev/issue/138): Linux sends out multiple UDP datagrams, each
+ // of the size of a page.
+ EXPECT_THAT(n, SyscallSucceedsWithValue(sizeof(buf)));
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(AllRawPacketMsgSizeTest, RawPacketMsgSizeTest,
+ ::testing::Values(V4Loopback(), V6Loopback()));
+
} // namespace
} // namespace testing
diff --git a/test/syscalls/linux/socket_test_util.cc b/test/syscalls/linux/socket_test_util.cc
index 26dacc95e..b2a96086c 100644
--- a/test/syscalls/linux/socket_test_util.cc
+++ b/test/syscalls/linux/socket_test_util.cc
@@ -791,6 +791,19 @@ void RecvNoData(int sock) {
SyscallFailsWithErrno(EAGAIN));
}
+TestAddress TestAddress::WithPort(uint16_t port) const {
+ TestAddress addr = *this;
+ switch (addr.family()) {
+ case AF_INET:
+ reinterpret_cast<sockaddr_in*>(&addr.addr)->sin_port = htons(port);
+ break;
+ case AF_INET6:
+ reinterpret_cast<sockaddr_in6*>(&addr.addr)->sin6_port = htons(port);
+ break;
+ }
+ return addr;
+}
+
TestAddress V4Any() {
TestAddress t("V4Any");
t.addr.ss_family = AF_INET;
diff --git a/test/syscalls/linux/socket_test_util.h b/test/syscalls/linux/socket_test_util.h
index 75c0d4735..b3ab286b8 100644
--- a/test/syscalls/linux/socket_test_util.h
+++ b/test/syscalls/linux/socket_test_util.h
@@ -486,9 +486,14 @@ struct TestAddress {
sockaddr_storage addr;
socklen_t addr_len;
- int family() const { return addr.ss_family; }
explicit TestAddress(std::string description = "")
: description(std::move(description)), addr(), addr_len() {}
+
+ int family() const { return addr.ss_family; }
+
+ // Returns a new TestAddress with specified port. If port is not supported,
+ // the same TestAddress is returned.
+ TestAddress WithPort(uint16_t port) const;
};
constexpr char kMulticastAddress[] = "224.0.2.1";