gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/util/socket_util.h (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GVISOR_TEST_SYSCALLS_SOCKET_TEST_UTIL_H_ 16 #define GVISOR_TEST_SYSCALLS_SOCKET_TEST_UTIL_H_ 17 18 #include <errno.h> 19 #include <netinet/ip.h> 20 #include <netinet/ip6.h> 21 #include <netinet/ip_icmp.h> 22 #include <netinet/udp.h> 23 #include <sys/socket.h> 24 #include <sys/types.h> 25 #include <sys/un.h> 26 27 #include <functional> 28 #include <memory> 29 #include <string> 30 #include <utility> 31 #include <vector> 32 33 #include "gtest/gtest.h" 34 #include "absl/strings/str_format.h" 35 #include "test/util/file_descriptor.h" 36 #include "test/util/posix_error.h" 37 #include "test/util/test_util.h" 38 39 namespace gvisor { 40 namespace testing { 41 42 // Wrapper for socket(2) that returns a FileDescriptor. 43 inline PosixErrorOr<FileDescriptor> Socket(int family, int type, int protocol) { 44 int fd = socket(family, type, protocol); 45 MaybeSave(); 46 if (fd < 0) { 47 return PosixError( 48 errno, absl::StrFormat("socket(%d, %d, %d)", family, type, protocol)); 49 } 50 return FileDescriptor(fd); 51 } 52 53 // Wrapper for accept(2) that returns a FileDescriptor. 54 inline PosixErrorOr<FileDescriptor> Accept(int sockfd, sockaddr* addr, 55 socklen_t* addrlen) { 56 int fd = RetryEINTR(accept)(sockfd, addr, addrlen); 57 MaybeSave(); 58 if (fd < 0) { 59 return PosixError( 60 errno, absl::StrFormat("accept(%d, %p, %p)", sockfd, addr, addrlen)); 61 } 62 return FileDescriptor(fd); 63 } 64 65 // Wrapper for accept4(2) that returns a FileDescriptor. 66 inline PosixErrorOr<FileDescriptor> Accept4(int sockfd, sockaddr* addr, 67 socklen_t* addrlen, int flags) { 68 int fd = RetryEINTR(accept4)(sockfd, addr, addrlen, flags); 69 MaybeSave(); 70 if (fd < 0) { 71 return PosixError(errno, absl::StrFormat("accept4(%d, %p, %p, %#x)", sockfd, 72 addr, addrlen, flags)); 73 } 74 return FileDescriptor(fd); 75 } 76 77 inline ssize_t SendFd(int fd, void* buf, size_t count, int flags) { 78 return internal::ApplyFileIoSyscall( 79 [&](size_t completed) { 80 return sendto(fd, static_cast<char*>(buf) + completed, 81 count - completed, flags, nullptr, 0); 82 }, 83 count); 84 } 85 86 PosixErrorOr<struct sockaddr_un> UniqueUnixAddr(bool abstract, int domain); 87 88 // A Creator<T> is a function that attempts to create and return a new T. (This 89 // is copy/pasted from cloud/gvisor/api/sandbox_util.h and is just duplicated 90 // here for clarity.) 91 template <typename T> 92 using Creator = std::function<PosixErrorOr<std::unique_ptr<T>>()>; 93 94 // A SocketPair represents a pair of socket file descriptors owned by the 95 // SocketPair. 96 class SocketPair { 97 public: 98 virtual ~SocketPair() = default; 99 100 virtual int first_fd() const = 0; 101 virtual int second_fd() const = 0; 102 virtual int release_first_fd() = 0; 103 virtual int release_second_fd() = 0; 104 virtual const struct sockaddr* first_addr() const = 0; 105 virtual const struct sockaddr* second_addr() const = 0; 106 virtual size_t first_addr_size() const = 0; 107 virtual size_t second_addr_size() const = 0; 108 virtual size_t first_addr_len() const = 0; 109 virtual size_t second_addr_len() const = 0; 110 }; 111 112 // A FDSocketPair is a SocketPair that consists of only a pair of file 113 // descriptors. 114 class FDSocketPair : public SocketPair { 115 public: 116 FDSocketPair(FileDescriptor first_fd, FileDescriptor second_fd) 117 : first_(std::move(first_fd)), second_(std::move(second_fd)) {} 118 FDSocketPair(std::unique_ptr<FileDescriptor> first_fd, 119 std::unique_ptr<FileDescriptor> second_fd) 120 : first_(first_fd->release()), second_(second_fd->release()) {} 121 122 int first_fd() const override { return first_.get(); } 123 int second_fd() const override { return second_.get(); } 124 int release_first_fd() override { return first_.release(); } 125 int release_second_fd() override { return second_.release(); } 126 const struct sockaddr* first_addr() const override { return nullptr; } 127 const struct sockaddr* second_addr() const override { return nullptr; } 128 size_t first_addr_size() const override { return 0; } 129 size_t second_addr_size() const override { return 0; } 130 size_t first_addr_len() const override { return 0; } 131 size_t second_addr_len() const override { return 0; } 132 133 private: 134 FileDescriptor first_; 135 FileDescriptor second_; 136 }; 137 138 // CalculateUnixSockAddrLen calculates the length returned by recvfrom(2) and 139 // recvmsg(2) for Unix sockets. 140 size_t CalculateUnixSockAddrLen(const char* sun_path); 141 142 // A AddrFDSocketPair is a SocketPair that consists of a pair of file 143 // descriptors in addition to a pair of socket addresses. 144 class AddrFDSocketPair : public SocketPair { 145 public: 146 AddrFDSocketPair(FileDescriptor first_fd, FileDescriptor second_fd, 147 const struct sockaddr_un& first_address, 148 const struct sockaddr_un& second_address) 149 : first_(std::move(first_fd)), 150 second_(std::move(second_fd)), 151 first_addr_(to_storage(first_address)), 152 second_addr_(to_storage(second_address)), 153 first_len_(CalculateUnixSockAddrLen(first_address.sun_path)), 154 second_len_(CalculateUnixSockAddrLen(second_address.sun_path)), 155 first_size_(sizeof(first_address)), 156 second_size_(sizeof(second_address)) {} 157 158 AddrFDSocketPair(FileDescriptor first_fd, FileDescriptor second_fd, 159 const struct sockaddr_in& first_address, 160 const struct sockaddr_in& second_address) 161 : first_(std::move(first_fd)), 162 second_(std::move(second_fd)), 163 first_addr_(to_storage(first_address)), 164 second_addr_(to_storage(second_address)), 165 first_len_(sizeof(first_address)), 166 second_len_(sizeof(second_address)), 167 first_size_(sizeof(first_address)), 168 second_size_(sizeof(second_address)) {} 169 170 AddrFDSocketPair(FileDescriptor first_fd, FileDescriptor second_fd, 171 const struct sockaddr_in6& first_address, 172 const struct sockaddr_in6& second_address) 173 : first_(std::move(first_fd)), 174 second_(std::move(second_fd)), 175 first_addr_(to_storage(first_address)), 176 second_addr_(to_storage(second_address)), 177 first_len_(sizeof(first_address)), 178 second_len_(sizeof(second_address)), 179 first_size_(sizeof(first_address)), 180 second_size_(sizeof(second_address)) {} 181 182 int first_fd() const override { return first_.get(); } 183 int second_fd() const override { return second_.get(); } 184 int release_first_fd() override { return first_.release(); } 185 int release_second_fd() override { return second_.release(); } 186 const struct sockaddr* first_addr() const override { 187 return reinterpret_cast<const struct sockaddr*>(&first_addr_); 188 } 189 const struct sockaddr* second_addr() const override { 190 return reinterpret_cast<const struct sockaddr*>(&second_addr_); 191 } 192 size_t first_addr_size() const override { return first_size_; } 193 size_t second_addr_size() const override { return second_size_; } 194 size_t first_addr_len() const override { return first_len_; } 195 size_t second_addr_len() const override { return second_len_; } 196 197 private: 198 // to_storage coverts a sockaddr_* to a sockaddr_storage. 199 static struct sockaddr_storage to_storage(const sockaddr_un& addr); 200 static struct sockaddr_storage to_storage(const sockaddr_in& addr); 201 static struct sockaddr_storage to_storage(const sockaddr_in6& addr); 202 203 FileDescriptor first_; 204 FileDescriptor second_; 205 const struct sockaddr_storage first_addr_; 206 const struct sockaddr_storage second_addr_; 207 const size_t first_len_; 208 const size_t second_len_; 209 const size_t first_size_; 210 const size_t second_size_; 211 }; 212 213 // SyscallSocketPairCreator returns a Creator<SocketPair> that obtains file 214 // descriptors by invoking the socketpair() syscall. 215 Creator<SocketPair> SyscallSocketPairCreator(int domain, int type, 216 int protocol); 217 218 // SyscallSocketCreator returns a Creator<FileDescriptor> that obtains a file 219 // descriptor by invoking the socket() syscall. 220 Creator<FileDescriptor> SyscallSocketCreator(int domain, int type, 221 int protocol); 222 223 // FilesystemBidirectionalBindSocketPairCreator returns a Creator<SocketPair> 224 // that obtains file descriptors by invoking the bind() and connect() syscalls 225 // on filesystem paths. Only works for DGRAM sockets. 226 Creator<SocketPair> FilesystemBidirectionalBindSocketPairCreator(int domain, 227 int type, 228 int protocol); 229 230 // AbstractBidirectionalBindSocketPairCreator returns a Creator<SocketPair> that 231 // obtains file descriptors by invoking the bind() and connect() syscalls on 232 // abstract namespace paths. Only works for DGRAM sockets. 233 Creator<SocketPair> AbstractBidirectionalBindSocketPairCreator(int domain, 234 int type, 235 int protocol); 236 237 // SocketpairGoferSocketPairCreator returns a Creator<SocketPair> that 238 // obtains file descriptors by connect() syscalls on two sockets with socketpair 239 // gofer paths. 240 Creator<SocketPair> SocketpairGoferSocketPairCreator(int domain, int type, 241 int protocol); 242 243 // SocketpairGoferFileSocketPairCreator returns a Creator<SocketPair> that 244 // obtains file descriptors by open() syscalls on socketpair gofer paths. 245 Creator<SocketPair> SocketpairGoferFileSocketPairCreator(int flags); 246 247 // FilesystemAcceptBindSocketPairCreator returns a Creator<SocketPair> that 248 // obtains file descriptors by invoking the accept() and bind() syscalls on 249 // a filesystem path. Only works for STREAM and SEQPACKET sockets. 250 Creator<SocketPair> FilesystemAcceptBindSocketPairCreator(int domain, int type, 251 int protocol); 252 253 // AbstractAcceptBindSocketPairCreator returns a Creator<SocketPair> that 254 // obtains file descriptors by invoking the accept() and bind() syscalls on a 255 // abstract namespace path. Only works for STREAM and SEQPACKET sockets. 256 Creator<SocketPair> AbstractAcceptBindSocketPairCreator(int domain, int type, 257 int protocol); 258 259 // FilesystemUnboundSocketPairCreator returns a Creator<SocketPair> that obtains 260 // file descriptors by invoking the socket() syscall and generates a filesystem 261 // path for binding. 262 Creator<SocketPair> FilesystemUnboundSocketPairCreator(int domain, int type, 263 int protocol); 264 265 // AbstractUnboundSocketPairCreator returns a Creator<SocketPair> that obtains 266 // file descriptors by invoking the socket() syscall and generates an abstract 267 // path for binding. 268 Creator<SocketPair> AbstractUnboundSocketPairCreator(int domain, int type, 269 int protocol); 270 271 // TCPAcceptBindSocketPairCreator returns a Creator<SocketPair> that obtains 272 // file descriptors by invoking the accept() and bind() syscalls on TCP sockets. 273 Creator<SocketPair> TCPAcceptBindSocketPairCreator(int domain, int type, 274 int protocol, 275 bool dual_stack); 276 277 // TCPAcceptBindPersistentListenerSocketPairCreator is like 278 // TCPAcceptBindSocketPairCreator, except it uses the same listening socket to 279 // create all SocketPairs. 280 Creator<SocketPair> TCPAcceptBindPersistentListenerSocketPairCreator( 281 int domain, int type, int protocol, bool dual_stack); 282 283 // UDPBidirectionalBindSocketPairCreator returns a Creator<SocketPair> that 284 // obtains file descriptors by invoking the bind() and connect() syscalls on UDP 285 // sockets. 286 Creator<SocketPair> UDPBidirectionalBindSocketPairCreator(int domain, int type, 287 int protocol, 288 bool dual_stack); 289 290 // UDPUnboundSocketPairCreator returns a Creator<SocketPair> that obtains file 291 // descriptors by creating UDP sockets. 292 Creator<SocketPair> UDPUnboundSocketPairCreator(int domain, int type, 293 int protocol, bool dual_stack); 294 295 // UnboundSocketCreator returns a Creator<FileDescriptor> that obtains a file 296 // descriptor by creating a socket. 297 Creator<FileDescriptor> UnboundSocketCreator(int domain, int type, 298 int protocol); 299 300 // A SocketPairKind couples a human-readable description of a socket pair with 301 // a function that creates such a socket pair. 302 struct SocketPairKind { 303 std::string description; 304 int domain; 305 int type; 306 int protocol; 307 Creator<SocketPair> creator; 308 309 // Create creates a socket pair of this kind. 310 PosixErrorOr<std::unique_ptr<SocketPair>> Create() const { return creator(); } 311 }; 312 313 // A SocketKind couples a human-readable description of a socket with 314 // a function that creates such a socket. 315 struct SocketKind { 316 std::string description; 317 int domain; 318 int type; 319 int protocol; 320 Creator<FileDescriptor> creator; 321 322 // Create creates a socket pair of this kind. 323 PosixErrorOr<std::unique_ptr<FileDescriptor>> Create() const { 324 return creator(); 325 } 326 }; 327 328 // A ReversedSocketPair wraps another SocketPair but flips the first and second 329 // file descriptors. ReversedSocketPair is used to test socket pairs that 330 // should be symmetric. 331 class ReversedSocketPair : public SocketPair { 332 public: 333 explicit ReversedSocketPair(std::unique_ptr<SocketPair> base) 334 : base_(std::move(base)) {} 335 336 int first_fd() const override { return base_->second_fd(); } 337 int second_fd() const override { return base_->first_fd(); } 338 int release_first_fd() override { return base_->release_second_fd(); } 339 int release_second_fd() override { return base_->release_first_fd(); } 340 const struct sockaddr* first_addr() const override { 341 return base_->second_addr(); 342 } 343 const struct sockaddr* second_addr() const override { 344 return base_->first_addr(); 345 } 346 size_t first_addr_size() const override { return base_->second_addr_size(); } 347 size_t second_addr_size() const override { return base_->first_addr_size(); } 348 size_t first_addr_len() const override { return base_->second_addr_len(); } 349 size_t second_addr_len() const override { return base_->first_addr_len(); } 350 351 private: 352 std::unique_ptr<SocketPair> base_; 353 }; 354 355 // Reversed returns a SocketPairKind that represents SocketPairs created by 356 // flipping the file descriptors provided by another SocketPair. 357 SocketPairKind Reversed(SocketPairKind const& base); 358 359 // IncludeReversals returns a vector<SocketPairKind> that returns all 360 // SocketPairKinds in `vec` as well as all SocketPairKinds obtained by flipping 361 // the file descriptors provided by the kinds in `vec`. 362 std::vector<SocketPairKind> IncludeReversals(std::vector<SocketPairKind> vec); 363 364 // A Middleware is a function wraps a SocketPairKind. 365 using Middleware = std::function<SocketPairKind(SocketPairKind)>; 366 367 // Reversed returns a SocketPairKind that represents SocketPairs created by 368 // flipping the file descriptors provided by another SocketPair. 369 template <typename T> 370 Middleware SetSockOpt(int level, int optname, T* value) { 371 return [=](SocketPairKind const& base) { 372 auto const& creator = base.creator; 373 return SocketPairKind{ 374 absl::StrCat("setsockopt(", level, ", ", optname, ", ", *value, ") ", 375 base.description), 376 base.domain, base.type, base.protocol, 377 [creator, level, optname, 378 value]() -> PosixErrorOr<std::unique_ptr<SocketPair>> { 379 ASSIGN_OR_RETURN_ERRNO(auto creator_value, creator()); 380 if (creator_value->first_fd() >= 0) { 381 RETURN_ERROR_IF_SYSCALL_FAIL(setsockopt( 382 creator_value->first_fd(), level, optname, value, sizeof(T))); 383 } 384 if (creator_value->second_fd() >= 0) { 385 RETURN_ERROR_IF_SYSCALL_FAIL(setsockopt( 386 creator_value->second_fd(), level, optname, value, sizeof(T))); 387 } 388 return creator_value; 389 }}; 390 }; 391 } 392 393 constexpr int kSockOptOn = 1; 394 constexpr int kSockOptOff = 0; 395 396 // NoOp returns the same SocketPairKind that it is passed. 397 SocketPairKind NoOp(SocketPairKind const& base); 398 399 // TransferTest tests that data can be send back and fourth between two 400 // specified FDs. Note that calls to this function should be wrapped in 401 // ASSERT_NO_FATAL_FAILURE(). 402 void TransferTest(int fd1, int fd2); 403 404 // Base test fixture for tests that operate on pairs of connected sockets. 405 class SocketPairTest : public ::testing::TestWithParam<SocketPairKind> { 406 protected: 407 SocketPairTest() { 408 // gUnit uses printf, so so will we. 409 printf("Testing with %s\n", GetParam().description.c_str()); 410 fflush(stdout); 411 } 412 413 PosixErrorOr<std::unique_ptr<SocketPair>> NewSocketPair() const { 414 return GetParam().Create(); 415 } 416 }; 417 418 // Base test fixture for tests that operate on simple Sockets. 419 class SimpleSocketTest : public ::testing::TestWithParam<SocketKind> { 420 protected: 421 SimpleSocketTest() { 422 // gUnit uses printf, so so will we. 423 printf("Testing with %s\n", GetParam().description.c_str()); 424 } 425 426 PosixErrorOr<std::unique_ptr<FileDescriptor>> NewSocket() const { 427 return GetParam().Create(); 428 } 429 }; 430 431 SocketKind SimpleSocket(int fam, int type, int proto); 432 433 // Send a buffer of size 'size' to sockets->first_fd(), returning the result of 434 // sendmsg. 435 // 436 // If reader, read from second_fd() until size bytes have been read. 437 ssize_t SendLargeSendMsg(const std::unique_ptr<SocketPair>& sockets, 438 size_t size, bool reader); 439 440 // Initializes the given buffer with random data. 441 void RandomizeBuffer(char* ptr, size_t len); 442 443 enum class AddressFamily { kIpv4 = 1, kIpv6 = 2, kDualStack = 3 }; 444 enum class SocketType { kUdp = 1, kTcp = 2 }; 445 446 // Returns a PosixError or a port that is available. If 0 is specified as the 447 // port it will bind port 0 (and allow the kernel to select any free port). 448 // Otherwise, it will try to bind the specified port and validate that it can be 449 // used for the requested family and socket type. The final option is 450 // reuse_addr. This specifies whether SO_REUSEADDR should be applied before a 451 // bind(2) attempt. SO_REUSEADDR means that sockets in TIME_WAIT states or other 452 // bound UDP sockets would not cause an error on bind(2). This option should be 453 // set if subsequent calls to bind on the returned port will also use 454 // SO_REUSEADDR. 455 // 456 // Note: That this test will attempt to bind the ANY address for the respective 457 // protocol. 458 PosixErrorOr<int> PortAvailable(int port, AddressFamily family, SocketType type, 459 bool reuse_addr); 460 461 // FreeAvailablePort is used to return a port that was obtained by using 462 // the PortAvailable helper with port 0. 463 PosixError FreeAvailablePort(int port); 464 465 // SendMsg converts a buffer to an iovec and adds it to msg before sending it. 466 PosixErrorOr<int> SendMsg(int sock, msghdr* msg, char buf[], int buf_size); 467 468 // RecvTimeout calls select on sock with timeout and then calls recv on sock. 469 PosixErrorOr<int> RecvTimeout(int sock, char buf[], int buf_size, int timeout); 470 471 // RecvMsgTimeout calls select on sock with timeout and then calls recvmsg on 472 // sock. 473 PosixErrorOr<int> RecvMsgTimeout(int sock, msghdr* msg, int timeout); 474 475 // RecvNoData checks that no data is receivable on sock. 476 void RecvNoData(int sock); 477 478 // Base test fixture for tests that apply to all kinds of pairs of connected 479 // sockets. 480 using AllSocketPairTest = SocketPairTest; 481 482 struct TestAddress { 483 std::string description; 484 sockaddr_storage addr; 485 socklen_t addr_len; 486 487 explicit TestAddress(std::string description = "") 488 : description(std::move(description)), addr(), addr_len() {} 489 490 int family() const { return addr.ss_family; } 491 492 // Returns a new TestAddress with specified port. If port is not supported, 493 // the same TestAddress is returned. 494 TestAddress WithPort(uint16_t port) const; 495 }; 496 497 constexpr char kMulticastAddress[] = "224.0.2.1"; 498 constexpr char kBroadcastAddress[] = "255.255.255.255"; 499 500 // Returns a TestAddress with `addr` parsed as an IPv4 address described by 501 // `description`. 502 TestAddress V4AddrStr(std::string description, const char* addr); 503 // Returns a TestAddress with `addr` parsed as an IPv6 address described by 504 // `description`. 505 TestAddress V6AddrStr(std::string description, const char* addr); 506 507 // Returns a TestAddress for the IPv4 any address. 508 TestAddress V4Any(); 509 // Returns a TestAddress for the IPv4 limited broadcast address. 510 TestAddress V4Broadcast(); 511 // Returns a TestAddress for the IPv4 loopback address. 512 TestAddress V4Loopback(); 513 // Returns a TestAddress for the subnet broadcast of the IPv4 loopback address. 514 TestAddress V4LoopbackSubnetBroadcast(); 515 // Returns a TestAddress for the IPv4-mapped IPv6 any address. 516 TestAddress V4MappedAny(); 517 // Returns a TestAddress for the IPv4-mapped IPv6 loopback address. 518 TestAddress V4MappedLoopback(); 519 // Returns a TestAddress for a IPv4 multicast address. 520 TestAddress V4Multicast(); 521 // Returns a TestAddress for the IPv4 all-hosts multicast group address. 522 TestAddress V4MulticastAllHosts(); 523 524 // Returns a TestAddress for the IPv6 any address. 525 TestAddress V6Any(); 526 // Returns a TestAddress for the IPv6 loopback address. 527 TestAddress V6Loopback(); 528 // Returns a TestAddress for a IPv6 multicast address. 529 TestAddress V6Multicast(); 530 // Returns a TestAddress for the IPv6 interface-local all-nodes multicast group 531 // address. 532 TestAddress V6MulticastInterfaceLocalAllNodes(); 533 // Returns a TestAddress for the IPv6 link-local all-nodes multicast group 534 // address. 535 TestAddress V6MulticastLinkLocalAllNodes(); 536 // Returns a TestAddress for the IPv6 link-local all-routers multicast group 537 // address. 538 TestAddress V6MulticastLinkLocalAllRouters(); 539 540 // Compute the internet checksum of an IP header. 541 uint16_t IPChecksum(struct iphdr ip); 542 543 // Compute the internet checksum of a UDP header. 544 uint16_t UDPChecksum(struct iphdr iphdr, struct udphdr udphdr, 545 const char* payload, ssize_t payload_len); 546 547 // Compute the internet checksum of a UDPv6 header. 548 uint16_t UDPChecksum(struct ip6_hdr iphdr, struct udphdr udphdr, 549 const char* payload, ssize_t payload_len); 550 551 // Compute the internet checksum of an ICMP header. 552 uint16_t ICMPChecksum(struct icmphdr icmphdr, const char* payload, 553 ssize_t payload_len); 554 555 // Convenient functions for reinterpreting common types to sockaddr pointer. 556 inline sockaddr* AsSockAddr(sockaddr_storage* s) { 557 return reinterpret_cast<sockaddr*>(s); 558 } 559 inline const sockaddr* AsSockAddr(const sockaddr_storage* s) { 560 return reinterpret_cast<const sockaddr*>(s); 561 } 562 inline sockaddr* AsSockAddr(sockaddr_in* s) { 563 return reinterpret_cast<sockaddr*>(s); 564 } 565 inline const sockaddr* AsSockAddr(const sockaddr_in* s) { 566 return reinterpret_cast<const sockaddr*>(s); 567 } 568 inline sockaddr* AsSockAddr(sockaddr_in6* s) { 569 return reinterpret_cast<sockaddr*>(s); 570 } 571 inline const sockaddr* AsSockAddr(const sockaddr_in6* s) { 572 return reinterpret_cast<const sockaddr*>(s); 573 } 574 inline sockaddr* AsSockAddr(sockaddr_un* s) { 575 return reinterpret_cast<sockaddr*>(s); 576 } 577 inline const sockaddr* AsSockAddr(const sockaddr_un* s) { 578 return reinterpret_cast<const sockaddr*>(s); 579 } 580 581 PosixErrorOr<uint16_t> AddrPort(int family, sockaddr_storage const& addr); 582 583 PosixError SetAddrPort(int family, sockaddr_storage* addr, uint16_t port); 584 585 sockaddr_storage InetLoopbackAddr(int family); 586 587 // setupTimeWaitClose sets up a socket endpoint in TIME_WAIT state. 588 // Callers can choose to perform active close on either ends of the connection 589 // and also specify if they want to enabled SO_REUSEADDR. 590 void SetupTimeWaitClose(const TestAddress* listener, 591 const TestAddress* connector, bool reuse, 592 bool accept_close, sockaddr_storage* listen_addr, 593 sockaddr_storage* conn_bound_addr); 594 595 // MaybeLimitEphemeralPorts attempts to reduce the number of ephemeral ports and 596 // returns the number of ephemeral ports. 597 PosixErrorOr<int> MaybeLimitEphemeralPorts(); 598 599 // AllowMartianPacketsOnLoopback tells the kernel to not drop martian packets, 600 // and returns a function to restore the original configuration. 601 PosixErrorOr<std::function<PosixError()>> AllowMartianPacketsOnLoopback(); 602 603 namespace internal { 604 PosixErrorOr<int> TryPortAvailable(int port, AddressFamily family, 605 SocketType type, bool reuse_addr); 606 } // namespace internal 607 608 } // namespace testing 609 } // namespace gvisor 610 611 #endif // GVISOR_TEST_SYSCALLS_SOCKET_TEST_UTIL_H_