gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/socket_ipv4_udp_unbound_netlink.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_ipv4_udp_unbound_netlink.h" 16 17 #include <arpa/inet.h> 18 #include <poll.h> 19 20 #include "gtest/gtest.h" 21 #include "test/syscalls/linux/socket_netlink_route_util.h" 22 #include "test/util/capability_util.h" 23 #include "test/util/cleanup.h" 24 25 namespace gvisor { 26 namespace testing { 27 28 constexpr size_t kSendBufSize = 200; 29 30 // Checks that the loopback interface considers itself bound to all IPs in an 31 // associated subnet. 32 TEST_P(IPv4UDPUnboundSocketNetlinkTest, JoinSubnet) { 33 SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN))); 34 35 // Add an IP address to the loopback interface. 36 Link loopback_link = ASSERT_NO_ERRNO_AND_VALUE(LoopbackLink()); 37 struct in_addr addr; 38 ASSERT_EQ(1, inet_pton(AF_INET, "192.0.2.1", &addr)); 39 ASSERT_NO_ERRNO(LinkAddLocalAddr(loopback_link.index, AF_INET, 40 /*prefixlen=*/24, &addr, sizeof(addr))); 41 Cleanup defer_addr_removal = Cleanup( 42 [loopback_link = std::move(loopback_link), addr = std::move(addr)] { 43 EXPECT_NO_ERRNO(LinkDelLocalAddr(loopback_link.index, AF_INET, 44 /*prefixlen=*/24, &addr, 45 sizeof(addr))); 46 }); 47 48 auto snd_sock = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 49 auto rcv_sock = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 50 51 // Send from an unassigned address but an address that is in the subnet 52 // associated with the loopback interface. 53 TestAddress sender_addr("V4NotAssignd1"); 54 sender_addr.addr.ss_family = AF_INET; 55 sender_addr.addr_len = sizeof(sockaddr_in); 56 ASSERT_EQ(1, inet_pton(AF_INET, "192.0.2.2", 57 &(reinterpret_cast<sockaddr_in*>(&sender_addr.addr) 58 ->sin_addr.s_addr))); 59 ASSERT_THAT(bind(snd_sock->get(), AsSockAddr(&sender_addr.addr), 60 sender_addr.addr_len), 61 SyscallSucceeds()); 62 63 // Send the packet to an unassigned address but an address that is in the 64 // subnet associated with the loopback interface. 65 TestAddress receiver_addr("V4NotAssigned2"); 66 receiver_addr.addr.ss_family = AF_INET; 67 receiver_addr.addr_len = sizeof(sockaddr_in); 68 ASSERT_EQ(1, inet_pton(AF_INET, "192.0.2.254", 69 &(reinterpret_cast<sockaddr_in*>(&receiver_addr.addr) 70 ->sin_addr.s_addr))); 71 ASSERT_THAT(bind(rcv_sock->get(), AsSockAddr(&receiver_addr.addr), 72 receiver_addr.addr_len), 73 SyscallSucceeds()); 74 socklen_t receiver_addr_len = receiver_addr.addr_len; 75 ASSERT_THAT(getsockname(rcv_sock->get(), AsSockAddr(&receiver_addr.addr), 76 &receiver_addr_len), 77 SyscallSucceeds()); 78 ASSERT_EQ(receiver_addr_len, receiver_addr.addr_len); 79 char send_buf[kSendBufSize]; 80 RandomizeBuffer(send_buf, kSendBufSize); 81 ASSERT_THAT(RetryEINTR(sendto)(snd_sock->get(), send_buf, kSendBufSize, 0, 82 AsSockAddr(&receiver_addr.addr), 83 receiver_addr.addr_len), 84 SyscallSucceedsWithValue(kSendBufSize)); 85 86 // Check that we received the packet. 87 char recv_buf[kSendBufSize] = {}; 88 ASSERT_THAT(RetryEINTR(recv)(rcv_sock->get(), recv_buf, kSendBufSize, 0), 89 SyscallSucceedsWithValue(kSendBufSize)); 90 ASSERT_EQ(0, memcmp(send_buf, recv_buf, kSendBufSize)); 91 } 92 93 // Tests that broadcast packets are delivered to all interested sockets 94 // (wildcard and broadcast address specified sockets). 95 // 96 // Note, we cannot test the IPv4 Broadcast (255.255.255.255) because we do 97 // not have a route to it. 98 TEST_P(IPv4UDPUnboundSocketNetlinkTest, ReuseAddrSubnetDirectedBroadcast) { 99 constexpr uint16_t kPort = 9876; 100 // Wait up to 20 seconds for the data. 101 constexpr int kPollTimeoutMs = 20000; 102 // Number of sockets per socket type. 103 constexpr int kNumSocketsPerType = 2; 104 105 SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN))); 106 107 // Add an IP address to the loopback interface. 108 Link loopback_link = ASSERT_NO_ERRNO_AND_VALUE(LoopbackLink()); 109 struct in_addr addr; 110 ASSERT_EQ(1, inet_pton(AF_INET, "192.0.2.1", &addr)); 111 ASSERT_NO_ERRNO(LinkAddLocalAddr(loopback_link.index, AF_INET, 112 24 /* prefixlen */, &addr, sizeof(addr))); 113 Cleanup defer_addr_removal = Cleanup( 114 [loopback_link = std::move(loopback_link), addr = std::move(addr)] { 115 EXPECT_NO_ERRNO(LinkDelLocalAddr(loopback_link.index, AF_INET, 116 /*prefixlen=*/24, &addr, 117 sizeof(addr))); 118 }); 119 120 TestAddress broadcast_address("SubnetBroadcastAddress"); 121 broadcast_address.addr.ss_family = AF_INET; 122 broadcast_address.addr_len = sizeof(sockaddr_in); 123 auto broadcast_address_in = 124 reinterpret_cast<sockaddr_in*>(&broadcast_address.addr); 125 ASSERT_EQ(1, inet_pton(AF_INET, "192.0.2.255", 126 &broadcast_address_in->sin_addr.s_addr)); 127 broadcast_address_in->sin_port = htons(kPort); 128 129 TestAddress any_address = V4Any(); 130 reinterpret_cast<sockaddr_in*>(&any_address.addr)->sin_port = htons(kPort); 131 132 // We create sockets bound to both the wildcard address and the broadcast 133 // address to make sure both of these types of "broadcast interested" sockets 134 // receive broadcast packets. 135 std::vector<std::unique_ptr<FileDescriptor>> socks; 136 for (bool bind_wildcard : {false, true}) { 137 // Create multiple sockets for each type of "broadcast interested" 138 // socket so we can test that all sockets receive the broadcast packet. 139 for (int i = 0; i < kNumSocketsPerType; i++) { 140 auto sock = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 141 auto idx = socks.size(); 142 143 ASSERT_THAT(setsockopt(sock->get(), SOL_SOCKET, SO_REUSEADDR, &kSockOptOn, 144 sizeof(kSockOptOn)), 145 SyscallSucceedsWithValue(0)) 146 << "socks[" << idx << "]"; 147 148 ASSERT_THAT(setsockopt(sock->get(), SOL_SOCKET, SO_BROADCAST, &kSockOptOn, 149 sizeof(kSockOptOn)), 150 SyscallSucceedsWithValue(0)) 151 << "socks[" << idx << "]"; 152 153 if (bind_wildcard) { 154 ASSERT_THAT(bind(sock->get(), AsSockAddr(&any_address.addr), 155 any_address.addr_len), 156 SyscallSucceeds()) 157 << "socks[" << idx << "]"; 158 } else { 159 ASSERT_THAT(bind(sock->get(), AsSockAddr(&broadcast_address.addr), 160 broadcast_address.addr_len), 161 SyscallSucceeds()) 162 << "socks[" << idx << "]"; 163 } 164 165 socks.push_back(std::move(sock)); 166 } 167 } 168 169 char send_buf[kSendBufSize]; 170 RandomizeBuffer(send_buf, kSendBufSize); 171 172 // Broadcasts from each socket should be received by every socket (including 173 // the sending socket). 174 for (size_t w = 0; w < socks.size(); w++) { 175 auto& w_sock = socks[w]; 176 ASSERT_THAT(RetryEINTR(sendto)(w_sock->get(), send_buf, kSendBufSize, 0, 177 AsSockAddr(&broadcast_address.addr), 178 broadcast_address.addr_len), 179 SyscallSucceedsWithValue(kSendBufSize)) 180 << "write socks[" << w << "]"; 181 182 // Check that we received the packet on all sockets. 183 for (size_t r = 0; r < socks.size(); r++) { 184 auto& r_sock = socks[r]; 185 186 struct pollfd poll_fd = {r_sock->get(), POLLIN, 0}; 187 EXPECT_THAT(RetryEINTR(poll)(&poll_fd, 1, kPollTimeoutMs), 188 SyscallSucceedsWithValue(1)) 189 << "write socks[" << w << "] & read socks[" << r << "]"; 190 191 char recv_buf[kSendBufSize] = {}; 192 EXPECT_THAT(RetryEINTR(recv)(r_sock->get(), recv_buf, kSendBufSize, 0), 193 SyscallSucceedsWithValue(kSendBufSize)) 194 << "write socks[" << w << "] & read socks[" << r << "]"; 195 EXPECT_EQ(0, memcmp(send_buf, recv_buf, kSendBufSize)) 196 << "write socks[" << w << "] & read socks[" << r << "]"; 197 } 198 } 199 } 200 201 } // namespace testing 202 } // namespace gvisor