github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/syscalls/linux/socket_ipv6_udp_unbound.cc (about) 1 // Copyright 2020 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 #include "test/syscalls/linux/socket_ipv6_udp_unbound.h" 16 17 #include <arpa/inet.h> 18 #include <netinet/in.h> 19 #ifdef __linux__ 20 #include <linux/in6.h> 21 #endif // __linux__ 22 #include <net/if.h> 23 #include <sys/ioctl.h> 24 #include <sys/socket.h> 25 #include <sys/types.h> 26 #include <sys/un.h> 27 28 #include <cstdio> 29 #include <cstring> 30 31 #include "gtest/gtest.h" 32 #include "absl/memory/memory.h" 33 #include "test/syscalls/linux/ip_socket_test_util.h" 34 #include "test/syscalls/linux/socket_test_util.h" 35 #include "test/util/posix_error.h" 36 #include "test/util/save_util.h" 37 #include "test/util/test_util.h" 38 39 namespace gvisor { 40 namespace testing { 41 42 // Test that socket will receive IP_RECVORIGDSTADDR control message. 43 TEST_P(IPv6UDPUnboundSocketTest, SetAndReceiveIPReceiveOrigDstAddr) { 44 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 45 auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 46 auto receiver_addr = V6Loopback(); 47 int level = SOL_IPV6; 48 int type = IPV6_RECVORIGDSTADDR; 49 50 ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), 51 receiver_addr.addr_len), 52 SyscallSucceeds()); 53 54 // Retrieve the port bound by the receiver. 55 socklen_t receiver_addr_len = receiver_addr.addr_len; 56 ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), 57 &receiver_addr_len), 58 SyscallSucceeds()); 59 EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); 60 61 ASSERT_THAT(connect(sender->get(), AsSockAddr(&receiver_addr.addr), 62 receiver_addr.addr_len), 63 SyscallSucceeds()); 64 65 // Get address and port bound by the sender. 66 sockaddr_storage sender_addr_storage; 67 socklen_t sender_addr_len = sizeof(sender_addr_storage); 68 ASSERT_THAT(getsockname(sender->get(), AsSockAddr(&sender_addr_storage), 69 &sender_addr_len), 70 SyscallSucceeds()); 71 ASSERT_EQ(sender_addr_len, sizeof(struct sockaddr_in6)); 72 73 // Enable IP_RECVORIGDSTADDR on socket so that we get the original destination 74 // address of the datagram as auxiliary information in the control message. 75 ASSERT_THAT( 76 setsockopt(receiver->get(), level, type, &kSockOptOn, sizeof(kSockOptOn)), 77 SyscallSucceeds()); 78 79 // Prepare message to send. 80 constexpr size_t kDataLength = 1024; 81 msghdr sent_msg = {}; 82 iovec sent_iov = {}; 83 char sent_data[kDataLength]; 84 sent_iov.iov_base = sent_data; 85 sent_iov.iov_len = kDataLength; 86 sent_msg.msg_iov = &sent_iov; 87 sent_msg.msg_iovlen = 1; 88 sent_msg.msg_flags = 0; 89 90 ASSERT_THAT(RetryEINTR(sendmsg)(sender->get(), &sent_msg, 0), 91 SyscallSucceedsWithValue(kDataLength)); 92 93 msghdr received_msg = {}; 94 iovec received_iov = {}; 95 char received_data[kDataLength]; 96 char received_cmsg_buf[CMSG_SPACE(sizeof(sockaddr_in6))] = {}; 97 size_t cmsg_data_len = sizeof(sockaddr_in6); 98 received_iov.iov_base = received_data; 99 received_iov.iov_len = kDataLength; 100 received_msg.msg_iov = &received_iov; 101 received_msg.msg_iovlen = 1; 102 received_msg.msg_controllen = CMSG_LEN(cmsg_data_len); 103 received_msg.msg_control = received_cmsg_buf; 104 105 ASSERT_THAT(RecvMsgTimeout(receiver->get(), &received_msg, 1 /*timeout*/), 106 IsPosixErrorOkAndHolds(kDataLength)); 107 108 cmsghdr* cmsg = CMSG_FIRSTHDR(&received_msg); 109 ASSERT_NE(cmsg, nullptr); 110 EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(cmsg_data_len)); 111 EXPECT_EQ(cmsg->cmsg_level, level); 112 EXPECT_EQ(cmsg->cmsg_type, type); 113 114 // Check that the received address in the control message matches the expected 115 // receiver's address. 116 sockaddr_in6 received_addr = {}; 117 memcpy(&received_addr, CMSG_DATA(cmsg), sizeof(received_addr)); 118 auto orig_receiver_addr = 119 reinterpret_cast<sockaddr_in6*>(&receiver_addr.addr); 120 EXPECT_EQ(memcmp(&received_addr.sin6_addr, &orig_receiver_addr->sin6_addr, 121 sizeof(in6_addr)), 122 0); 123 EXPECT_EQ(received_addr.sin6_port, orig_receiver_addr->sin6_port); 124 } 125 126 } // namespace testing 127 } // namespace gvisor