summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls/linux
diff options
context:
space:
mode:
authorRahat Mahmood <rahat@google.com>2019-06-13 17:23:35 -0700
committerShentubot <shentubot@google.com>2019-06-13 17:24:51 -0700
commit05ff1ffaadaa0ac370365eb14febc761506735ce (patch)
treee6505afe1536c60c7a2e362aa8355e01ec34f91a /test/syscalls/linux
parent7b0f068258146b4081060ae793ba6b73399f1452 (diff)
Implement getsockopt() SO_DOMAIN, SO_PROTOCOL and SO_TYPE.
SO_TYPE was already implemented for everything but netlink sockets. PiperOrigin-RevId: 253138157
Diffstat (limited to 'test/syscalls/linux')
-rw-r--r--test/syscalls/linux/BUILD2
-rw-r--r--test/syscalls/linux/ip_socket_test_util.cc51
-rw-r--r--test/syscalls/linux/socket_generic.cc50
-rw-r--r--test/syscalls/linux/socket_netlink_route.cc45
-rw-r--r--test/syscalls/linux/socket_test_util.cc7
-rw-r--r--test/syscalls/linux/socket_test_util.h7
-rw-r--r--test/syscalls/linux/unix_domain_socket_test_util.cc19
7 files changed, 143 insertions, 38 deletions
diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD
index 9bafc6e4f..2f6704842 100644
--- a/test/syscalls/linux/BUILD
+++ b/test/syscalls/linux/BUILD
@@ -1909,6 +1909,7 @@ cc_library(
":unix_domain_socket_test_util",
"//test/util:test_util",
"@com_google_absl//absl/strings",
+ "@com_google_absl//absl/strings:str_format",
"@com_google_googletest//:gtest",
],
alwayslink = 1,
@@ -2427,6 +2428,7 @@ cc_binary(
"//test/util:file_descriptor",
"//test/util:test_main",
"//test/util:test_util",
+ "@com_google_absl//absl/strings:str_format",
"@com_google_googletest//:gtest",
],
)
diff --git a/test/syscalls/linux/ip_socket_test_util.cc b/test/syscalls/linux/ip_socket_test_util.cc
index 7612919d4..5fc4e9115 100644
--- a/test/syscalls/linux/ip_socket_test_util.cc
+++ b/test/syscalls/linux/ip_socket_test_util.cc
@@ -45,70 +45,79 @@ SocketPairKind IPv6TCPAcceptBindSocketPair(int type) {
std::string description =
absl::StrCat(DescribeSocketType(type), "connected IPv6 TCP socket");
return SocketPairKind{
- description, TCPAcceptBindSocketPairCreator(AF_INET6, type | SOCK_STREAM,
- 0, /* dual_stack = */ false)};
+ description, AF_INET6, type | SOCK_STREAM, IPPROTO_TCP,
+ TCPAcceptBindSocketPairCreator(AF_INET6, type | SOCK_STREAM, 0,
+ /* dual_stack = */ false)};
}
SocketPairKind IPv4TCPAcceptBindSocketPair(int type) {
std::string description =
absl::StrCat(DescribeSocketType(type), "connected IPv4 TCP socket");
return SocketPairKind{
- description, TCPAcceptBindSocketPairCreator(AF_INET, type | SOCK_STREAM,
- 0, /* dual_stack = */ false)};
+ description, AF_INET, type | SOCK_STREAM, IPPROTO_TCP,
+ TCPAcceptBindSocketPairCreator(AF_INET, type | SOCK_STREAM, 0,
+ /* dual_stack = */ false)};
}
SocketPairKind DualStackTCPAcceptBindSocketPair(int type) {
std::string description =
absl::StrCat(DescribeSocketType(type), "connected dual stack TCP socket");
return SocketPairKind{
- description, TCPAcceptBindSocketPairCreator(AF_INET6, type | SOCK_STREAM,
- 0, /* dual_stack = */ true)};
+ description, AF_INET6, type | SOCK_STREAM, IPPROTO_TCP,
+ TCPAcceptBindSocketPairCreator(AF_INET6, type | SOCK_STREAM, 0,
+ /* dual_stack = */ true)};
}
SocketPairKind IPv6UDPBidirectionalBindSocketPair(int type) {
std::string description =
absl::StrCat(DescribeSocketType(type), "connected IPv6 UDP socket");
- return SocketPairKind{description, UDPBidirectionalBindSocketPairCreator(
- AF_INET6, type | SOCK_DGRAM, 0,
- /* dual_stack = */ false)};
+ return SocketPairKind{
+ description, AF_INET6, type | SOCK_DGRAM, IPPROTO_UDP,
+ UDPBidirectionalBindSocketPairCreator(AF_INET6, type | SOCK_DGRAM, 0,
+ /* dual_stack = */ false)};
}
SocketPairKind IPv4UDPBidirectionalBindSocketPair(int type) {
std::string description =
absl::StrCat(DescribeSocketType(type), "connected IPv4 UDP socket");
- return SocketPairKind{description, UDPBidirectionalBindSocketPairCreator(
- AF_INET, type | SOCK_DGRAM, 0,
- /* dual_stack = */ false)};
+ return SocketPairKind{
+ description, AF_INET, type | SOCK_DGRAM, IPPROTO_UDP,
+ UDPBidirectionalBindSocketPairCreator(AF_INET, type | SOCK_DGRAM, 0,
+ /* dual_stack = */ false)};
}
SocketPairKind DualStackUDPBidirectionalBindSocketPair(int type) {
std::string description =
absl::StrCat(DescribeSocketType(type), "connected dual stack UDP socket");
- return SocketPairKind{description, UDPBidirectionalBindSocketPairCreator(
- AF_INET6, type | SOCK_DGRAM, 0,
- /* dual_stack = */ true)};
+ return SocketPairKind{
+ description, AF_INET6, type | SOCK_DGRAM, IPPROTO_UDP,
+ UDPBidirectionalBindSocketPairCreator(AF_INET6, type | SOCK_DGRAM, 0,
+ /* dual_stack = */ true)};
}
SocketPairKind IPv4UDPUnboundSocketPair(int type) {
std::string description =
absl::StrCat(DescribeSocketType(type), "IPv4 UDP socket");
return SocketPairKind{
- description, UDPUnboundSocketPairCreator(AF_INET, type | SOCK_DGRAM, 0,
- /* dual_stack = */ false)};
+ description, AF_INET, type | SOCK_DGRAM, IPPROTO_UDP,
+ UDPUnboundSocketPairCreator(AF_INET, type | SOCK_DGRAM, 0,
+ /* dual_stack = */ false)};
}
SocketKind IPv4UDPUnboundSocket(int type) {
std::string description =
absl::StrCat(DescribeSocketType(type), "IPv4 UDP socket");
- return SocketKind{description, UnboundSocketCreator(
- AF_INET, type | SOCK_DGRAM, IPPROTO_UDP)};
+ return SocketKind{
+ description, AF_INET, type | SOCK_DGRAM, IPPROTO_UDP,
+ UnboundSocketCreator(AF_INET, type | SOCK_DGRAM, IPPROTO_UDP)};
}
SocketKind IPv4TCPUnboundSocket(int type) {
std::string description =
absl::StrCat(DescribeSocketType(type), "IPv4 TCP socket");
- return SocketKind{description, UnboundSocketCreator(
- AF_INET, type | SOCK_STREAM, IPPROTO_TCP)};
+ return SocketKind{
+ description, AF_INET, type | SOCK_STREAM, IPPROTO_TCP,
+ UnboundSocketCreator(AF_INET, type | SOCK_STREAM, IPPROTO_TCP)};
}
} // namespace testing
diff --git a/test/syscalls/linux/socket_generic.cc b/test/syscalls/linux/socket_generic.cc
index f99f3fe62..51d614639 100644
--- a/test/syscalls/linux/socket_generic.cc
+++ b/test/syscalls/linux/socket_generic.cc
@@ -21,6 +21,7 @@
#include "gtest/gtest.h"
#include "gtest/gtest.h"
+#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "test/syscalls/linux/socket_test_util.h"
#include "test/syscalls/linux/unix_domain_socket_test_util.h"
@@ -687,5 +688,54 @@ TEST_P(AllSocketPairTest, RecvTimeoutWaitAll) {
EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
}
+TEST_P(AllSocketPairTest, GetSockoptType) {
+ int type = GetParam().type;
+ auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
+ for (const int fd : {sockets->first_fd(), sockets->second_fd()}) {
+ int opt;
+ socklen_t optlen = sizeof(opt);
+ EXPECT_THAT(getsockopt(fd, SOL_SOCKET, SO_TYPE, &opt, &optlen),
+ SyscallSucceeds());
+
+ // Type may have SOCK_NONBLOCK and SOCK_CLOEXEC ORed into it. Remove these
+ // before comparison.
+ type &= ~(SOCK_NONBLOCK | SOCK_CLOEXEC);
+ EXPECT_EQ(opt, type) << absl::StrFormat(
+ "getsockopt(%d, SOL_SOCKET, SO_TYPE, &opt, &optlen) => opt=%d was "
+ "unexpected",
+ fd, opt);
+ }
+}
+
+TEST_P(AllSocketPairTest, GetSockoptDomain) {
+ const int domain = GetParam().domain;
+ auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
+ for (const int fd : {sockets->first_fd(), sockets->second_fd()}) {
+ int opt;
+ socklen_t optlen = sizeof(opt);
+ EXPECT_THAT(getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &opt, &optlen),
+ SyscallSucceeds());
+ EXPECT_EQ(opt, domain) << absl::StrFormat(
+ "getsockopt(%d, SOL_SOCKET, SO_DOMAIN, &opt, &optlen) => opt=%d was "
+ "unexpected",
+ fd, opt);
+ }
+}
+
+TEST_P(AllSocketPairTest, GetSockoptProtocol) {
+ const int protocol = GetParam().protocol;
+ auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
+ for (const int fd : {sockets->first_fd(), sockets->second_fd()}) {
+ int opt;
+ socklen_t optlen = sizeof(opt);
+ EXPECT_THAT(getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &opt, &optlen),
+ SyscallSucceeds());
+ EXPECT_EQ(opt, protocol) << absl::StrFormat(
+ "getsockopt(%d, SOL_SOCKET, SO_PROTOCOL, &opt, &optlen) => opt=%d was "
+ "unexpected",
+ fd, opt);
+ }
+}
+
} // namespace testing
} // namespace gvisor
diff --git a/test/syscalls/linux/socket_netlink_route.cc b/test/syscalls/linux/socket_netlink_route.cc
index c8693225f..53dd1ca78 100644
--- a/test/syscalls/linux/socket_netlink_route.cc
+++ b/test/syscalls/linux/socket_netlink_route.cc
@@ -23,6 +23,7 @@
#include <vector>
#include "gtest/gtest.h"
+#include "absl/strings/str_format.h"
#include "test/syscalls/linux/socket_netlink_util.h"
#include "test/syscalls/linux/socket_test_util.h"
#include "test/util/cleanup.h"
@@ -144,24 +145,56 @@ TEST(NetlinkRouteTest, GetPeerName) {
EXPECT_EQ(addr.nl_pid, 0);
}
-using IntSockOptTest = ::testing::TestWithParam<int>;
+// Parameters for GetSockOpt test. They are:
+// 0: Socket option to query.
+// 1: A predicate to run on the returned sockopt value. Should return true if
+// the value is considered ok.
+// 2: A description of what the sockopt value is expected to be. Should complete
+// the sentence "<value> was unexpected, expected <description>"
+using SockOptTest =
+ ::testing::TestWithParam<std::tuple<int, std::function<bool(int)>, std::string>>;
+
+TEST_P(SockOptTest, GetSockOpt) {
+ int sockopt = std::get<0>(GetParam());
+ auto verifier = std::get<1>(GetParam());
+ std::string verifier_description = std::get<2>(GetParam());
-TEST_P(IntSockOptTest, GetSockOpt) {
FileDescriptor fd =
ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE));
int res;
socklen_t len = sizeof(res);
- EXPECT_THAT(getsockopt(fd.get(), SOL_SOCKET, GetParam(), &res, &len),
+ EXPECT_THAT(getsockopt(fd.get(), SOL_SOCKET, sockopt, &res, &len),
SyscallSucceeds());
EXPECT_EQ(len, sizeof(res));
- EXPECT_GT(res, 0);
+ EXPECT_TRUE(verifier(res)) << absl::StrFormat(
+ "getsockopt(%d, SOL_SOCKET, %d, &res, &len) => res=%d was unexpected, "
+ "expected %s",
+ fd.get(), sockopt, res, verifier_description);
+}
+
+std::function<bool(int)> IsPositive() {
+ return [](int val) { return val > 0; };
+}
+
+std::function<bool(int)> IsEqual(int target) {
+ return [target](int val) { return val == target; };
}
-INSTANTIATE_TEST_SUITE_P(NetlinkRouteTest, IntSockOptTest,
- ::testing::Values(SO_SNDBUF, SO_RCVBUF));
+INSTANTIATE_TEST_SUITE_P(
+ NetlinkRouteTest, SockOptTest,
+ ::testing::Values(
+ std::make_tuple(SO_SNDBUF, IsPositive(), "positive send buffer size"),
+ std::make_tuple(SO_RCVBUF, IsPositive(),
+ "positive receive buffer size"),
+ std::make_tuple(SO_TYPE, IsEqual(SOCK_RAW),
+ absl::StrFormat("SOCK_RAW (%d)", SOCK_RAW)),
+ std::make_tuple(SO_DOMAIN, IsEqual(AF_NETLINK),
+ absl::StrFormat("AF_NETLINK (%d)", AF_NETLINK)),
+ std::make_tuple(SO_PROTOCOL, IsEqual(NETLINK_ROUTE),
+ absl::StrFormat("NETLINK_ROUTE (%d)", NETLINK_ROUTE))));
// Validates the reponses to RTM_GETLINK + NLM_F_DUMP.
void CheckGetLinkResponse(const struct nlmsghdr* hdr, int seq, int port) {
diff --git a/test/syscalls/linux/socket_test_util.cc b/test/syscalls/linux/socket_test_util.cc
index da69de37c..4f65cf5ae 100644
--- a/test/syscalls/linux/socket_test_util.cc
+++ b/test/syscalls/linux/socket_test_util.cc
@@ -457,7 +457,8 @@ Creator<SocketPair> UDPUnboundSocketPairCreator(int domain, int type,
SocketPairKind Reversed(SocketPairKind const& base) {
auto const& creator = base.creator;
return SocketPairKind{
- absl::StrCat("reversed ", base.description),
+ absl::StrCat("reversed ", base.description), base.domain, base.type,
+ base.protocol,
[creator]() -> PosixErrorOr<std::unique_ptr<ReversedSocketPair>> {
ASSIGN_OR_RETURN_ERRNO(auto creator_value, creator());
return absl::make_unique<ReversedSocketPair>(std::move(creator_value));
@@ -542,8 +543,8 @@ struct sockaddr_storage AddrFDSocketPair::to_storage(const sockaddr_in6& addr) {
SocketKind SimpleSocket(int fam, int type, int proto) {
return SocketKind{
- absl::StrCat("Family ", fam, ", type ", type, ", proto ", proto),
- SyscallSocketCreator(fam, type, proto)};
+ absl::StrCat("Family ", fam, ", type ", type, ", proto ", proto), fam,
+ type, proto, SyscallSocketCreator(fam, type, proto)};
}
ssize_t SendLargeSendMsg(const std::unique_ptr<SocketPair>& sockets,
diff --git a/test/syscalls/linux/socket_test_util.h b/test/syscalls/linux/socket_test_util.h
index 058313986..4fd59767a 100644
--- a/test/syscalls/linux/socket_test_util.h
+++ b/test/syscalls/linux/socket_test_util.h
@@ -287,6 +287,9 @@ Creator<FileDescriptor> UnboundSocketCreator(int domain, int type,
// a function that creates such a socket pair.
struct SocketPairKind {
std::string description;
+ int domain;
+ int type;
+ int protocol;
Creator<SocketPair> creator;
// Create creates a socket pair of this kind.
@@ -297,6 +300,9 @@ struct SocketPairKind {
// a function that creates such a socket.
struct SocketKind {
std::string description;
+ int domain;
+ int type;
+ int protocol;
Creator<FileDescriptor> creator;
// Create creates a socket pair of this kind.
@@ -353,6 +359,7 @@ Middleware SetSockOpt(int level, int optname, T* value) {
return SocketPairKind{
absl::StrCat("setsockopt(", level, ", ", optname, ", ", *value, ") ",
base.description),
+ base.domain, base.type, base.protocol,
[creator, level, optname,
value]() -> PosixErrorOr<std::unique_ptr<SocketPair>> {
ASSIGN_OR_RETURN_ERRNO(auto creator_value, creator());
diff --git a/test/syscalls/linux/unix_domain_socket_test_util.cc b/test/syscalls/linux/unix_domain_socket_test_util.cc
index 6f49e3660..ff28850b2 100644
--- a/test/syscalls/linux/unix_domain_socket_test_util.cc
+++ b/test/syscalls/linux/unix_domain_socket_test_util.cc
@@ -47,7 +47,7 @@ std::string DescribeUnixDomainSocketType(int type) {
}
SocketPairKind UnixDomainSocketPair(int type) {
- return SocketPairKind{DescribeUnixDomainSocketType(type),
+ return SocketPairKind{DescribeUnixDomainSocketType(type), AF_UNIX, type, 0,
SyscallSocketPairCreator(AF_UNIX, type, 0)};
}
@@ -56,11 +56,12 @@ SocketPairKind FilesystemBoundUnixDomainSocketPair(int type) {
" created with filesystem binding");
if ((type & SOCK_DGRAM) == SOCK_DGRAM) {
return SocketPairKind{
- description,
+ description, AF_UNIX, type, 0,
FilesystemBidirectionalBindSocketPairCreator(AF_UNIX, type, 0)};
}
return SocketPairKind{
- description, FilesystemAcceptBindSocketPairCreator(AF_UNIX, type, 0)};
+ description, AF_UNIX, type, 0,
+ FilesystemAcceptBindSocketPairCreator(AF_UNIX, type, 0)};
}
SocketPairKind AbstractBoundUnixDomainSocketPair(int type) {
@@ -68,17 +69,17 @@ SocketPairKind AbstractBoundUnixDomainSocketPair(int type) {
" created with abstract namespace binding");
if ((type & SOCK_DGRAM) == SOCK_DGRAM) {
return SocketPairKind{
- description,
+ description, AF_UNIX, type, 0,
AbstractBidirectionalBindSocketPairCreator(AF_UNIX, type, 0)};
}
- return SocketPairKind{description,
+ return SocketPairKind{description, AF_UNIX, type, 0,
AbstractAcceptBindSocketPairCreator(AF_UNIX, type, 0)};
}
SocketPairKind SocketpairGoferUnixDomainSocketPair(int type) {
std::string description = absl::StrCat(DescribeUnixDomainSocketType(type),
" created with the socketpair gofer");
- return SocketPairKind{description,
+ return SocketPairKind{description, AF_UNIX, type, 0,
SocketpairGoferSocketPairCreator(AF_UNIX, type, 0)};
}
@@ -87,13 +88,15 @@ SocketPairKind SocketpairGoferFileSocketPair(int type) {
absl::StrCat(((type & O_NONBLOCK) != 0) ? "non-blocking " : "",
((type & O_CLOEXEC) != 0) ? "close-on-exec " : "",
"file socket created with the socketpair gofer");
- return SocketPairKind{description,
+ // The socketpair gofer always creates SOCK_STREAM sockets on open(2).
+ return SocketPairKind{description, AF_UNIX, SOCK_STREAM, 0,
SocketpairGoferFileSocketPairCreator(type)};
}
SocketPairKind FilesystemUnboundUnixDomainSocketPair(int type) {
return SocketPairKind{absl::StrCat(DescribeUnixDomainSocketType(type),
" unbound with a filesystem address"),
+ AF_UNIX, type, 0,
FilesystemUnboundSocketPairCreator(AF_UNIX, type, 0)};
}
@@ -101,7 +104,7 @@ SocketPairKind AbstractUnboundUnixDomainSocketPair(int type) {
return SocketPairKind{
absl::StrCat(DescribeUnixDomainSocketType(type),
" unbound with an abstract namespace address"),
- AbstractUnboundSocketPairCreator(AF_UNIX, type, 0)};
+ AF_UNIX, type, 0, AbstractUnboundSocketPairCreator(AF_UNIX, type, 0)};
}
void SendSingleFD(int sock, int fd, char buf[], int buf_size) {