github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc (about) 1 // Copyright 2019 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_external_networking.h" 16 17 namespace gvisor { 18 namespace testing { 19 20 TestAddress V4EmptyAddress() { 21 TestAddress t("V4Empty"); 22 t.addr.ss_family = AF_INET; 23 t.addr_len = sizeof(sockaddr_in); 24 return t; 25 } 26 27 // Verifies that a broadcast UDP packet will arrive at all UDP sockets with 28 // the destination port number. 29 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 30 UDPBroadcastReceivedOnExpectedPort) { 31 SKIP_IF(!found_net_interfaces_); 32 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 33 auto rcvr1 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 34 auto rcvr2 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 35 auto norcv = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 36 37 // Enable SO_BROADCAST on the sending socket. 38 ASSERT_THAT(setsockopt(sender->get(), SOL_SOCKET, SO_BROADCAST, &kSockOptOn, 39 sizeof(kSockOptOn)), 40 SyscallSucceedsWithValue(0)); 41 42 // Enable SO_REUSEPORT on the receiving sockets so that they may both be bound 43 // to the broadcast messages destination port. 44 ASSERT_THAT(setsockopt(rcvr1->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, 45 sizeof(kSockOptOn)), 46 SyscallSucceedsWithValue(0)); 47 ASSERT_THAT(setsockopt(rcvr2->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, 48 sizeof(kSockOptOn)), 49 SyscallSucceedsWithValue(0)); 50 51 // Bind the first socket to the ANY address and let the system assign a port. 52 auto rcv1_addr = V4Any(); 53 ASSERT_THAT( 54 bind(rcvr1->get(), AsSockAddr(&rcv1_addr.addr), rcv1_addr.addr_len), 55 SyscallSucceedsWithValue(0)); 56 // Retrieve port number from first socket so that it can be bound to the 57 // second socket. 58 socklen_t rcv_addr_sz = rcv1_addr.addr_len; 59 ASSERT_THAT( 60 getsockname(rcvr1->get(), AsSockAddr(&rcv1_addr.addr), &rcv_addr_sz), 61 SyscallSucceedsWithValue(0)); 62 EXPECT_EQ(rcv_addr_sz, rcv1_addr.addr_len); 63 auto port = reinterpret_cast<sockaddr_in*>(&rcv1_addr.addr)->sin_port; 64 65 // Bind the second socket to the same address:port as the first. 66 ASSERT_THAT(bind(rcvr2->get(), AsSockAddr(&rcv1_addr.addr), rcv_addr_sz), 67 SyscallSucceedsWithValue(0)); 68 69 // Bind the non-receiving socket to an ephemeral port. 70 auto norecv_addr = V4Any(); 71 ASSERT_THAT( 72 bind(norcv->get(), AsSockAddr(&norecv_addr.addr), norecv_addr.addr_len), 73 SyscallSucceedsWithValue(0)); 74 75 // Broadcast a test message. 76 auto dst_addr = V4Broadcast(); 77 reinterpret_cast<sockaddr_in*>(&dst_addr.addr)->sin_port = port; 78 constexpr char kTestMsg[] = "hello, world"; 79 EXPECT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, 80 AsSockAddr(&dst_addr.addr), dst_addr.addr_len), 81 SyscallSucceedsWithValue(sizeof(kTestMsg))); 82 83 // Verify that the receiving sockets received the test message. 84 char buf[sizeof(kTestMsg)] = {}; 85 EXPECT_THAT(recv(rcvr1->get(), buf, sizeof(buf), 0), 86 SyscallSucceedsWithValue(sizeof(kTestMsg))); 87 EXPECT_EQ(0, memcmp(buf, kTestMsg, sizeof(kTestMsg))); 88 memset(buf, 0, sizeof(buf)); 89 EXPECT_THAT(recv(rcvr2->get(), buf, sizeof(buf), 0), 90 SyscallSucceedsWithValue(sizeof(kTestMsg))); 91 EXPECT_EQ(0, memcmp(buf, kTestMsg, sizeof(kTestMsg))); 92 93 // Verify that the non-receiving socket did not receive the test message. 94 memset(buf, 0, sizeof(buf)); 95 EXPECT_THAT(RetryEINTR(recv)(norcv->get(), buf, sizeof(buf), MSG_DONTWAIT), 96 SyscallFailsWithErrno(EAGAIN)); 97 } 98 99 // Verifies that a broadcast UDP packet will arrive at all UDP sockets bound to 100 // the destination port number and either INADDR_ANY or INADDR_BROADCAST, but 101 // not a unicast address. 102 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 103 UDPBroadcastReceivedOnExpectedAddresses) { 104 SKIP_IF(!found_net_interfaces_); 105 106 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 107 auto rcvr1 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 108 auto rcvr2 = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 109 auto norcv = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 110 111 // Enable SO_BROADCAST on the sending socket. 112 ASSERT_THAT(setsockopt(sender->get(), SOL_SOCKET, SO_BROADCAST, &kSockOptOn, 113 sizeof(kSockOptOn)), 114 SyscallSucceedsWithValue(0)); 115 116 // Enable SO_REUSEPORT on all sockets so that they may all be bound to the 117 // broadcast messages destination port. 118 ASSERT_THAT(setsockopt(rcvr1->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, 119 sizeof(kSockOptOn)), 120 SyscallSucceedsWithValue(0)); 121 ASSERT_THAT(setsockopt(rcvr2->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, 122 sizeof(kSockOptOn)), 123 SyscallSucceedsWithValue(0)); 124 ASSERT_THAT(setsockopt(norcv->get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, 125 sizeof(kSockOptOn)), 126 SyscallSucceedsWithValue(0)); 127 128 // Bind the first socket the ANY address and let the system assign a port. 129 auto rcv1_addr = V4Any(); 130 ASSERT_THAT( 131 bind(rcvr1->get(), AsSockAddr(&rcv1_addr.addr), rcv1_addr.addr_len), 132 SyscallSucceedsWithValue(0)); 133 // Retrieve port number from first socket so that it can be bound to the 134 // second socket. 135 socklen_t rcv_addr_sz = rcv1_addr.addr_len; 136 ASSERT_THAT( 137 getsockname(rcvr1->get(), AsSockAddr(&rcv1_addr.addr), &rcv_addr_sz), 138 SyscallSucceedsWithValue(0)); 139 EXPECT_EQ(rcv_addr_sz, rcv1_addr.addr_len); 140 auto port = reinterpret_cast<sockaddr_in*>(&rcv1_addr.addr)->sin_port; 141 142 // Bind the second socket to the broadcast address. 143 auto rcv2_addr = V4Broadcast(); 144 reinterpret_cast<sockaddr_in*>(&rcv2_addr.addr)->sin_port = port; 145 ASSERT_THAT( 146 bind(rcvr2->get(), AsSockAddr(&rcv2_addr.addr), rcv2_addr.addr_len), 147 SyscallSucceedsWithValue(0)); 148 149 // Bind the non-receiving socket to the unicast ethernet address. 150 auto norecv_addr = rcv1_addr; 151 reinterpret_cast<sockaddr_in*>(&norecv_addr.addr)->sin_addr = 152 eth_if_addr_.sin_addr; 153 ASSERT_THAT( 154 bind(norcv->get(), AsSockAddr(&norecv_addr.addr), norecv_addr.addr_len), 155 SyscallSucceedsWithValue(0)); 156 157 // Broadcast a test message. 158 auto dst_addr = V4Broadcast(); 159 reinterpret_cast<sockaddr_in*>(&dst_addr.addr)->sin_port = port; 160 constexpr char kTestMsg[] = "hello, world"; 161 EXPECT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, 162 AsSockAddr(&dst_addr.addr), dst_addr.addr_len), 163 SyscallSucceedsWithValue(sizeof(kTestMsg))); 164 165 // Verify that the receiving sockets received the test message. 166 char buf[sizeof(kTestMsg)] = {}; 167 EXPECT_THAT(recv(rcvr1->get(), buf, sizeof(buf), 0), 168 SyscallSucceedsWithValue(sizeof(kTestMsg))); 169 EXPECT_EQ(0, memcmp(buf, kTestMsg, sizeof(kTestMsg))); 170 memset(buf, 0, sizeof(buf)); 171 EXPECT_THAT(recv(rcvr2->get(), buf, sizeof(buf), 0), 172 SyscallSucceedsWithValue(sizeof(kTestMsg))); 173 EXPECT_EQ(0, memcmp(buf, kTestMsg, sizeof(kTestMsg))); 174 175 // Verify that the non-receiving socket did not receive the test message. 176 memset(buf, 0, sizeof(buf)); 177 EXPECT_THAT(RetryEINTR(recv)(norcv->get(), buf, sizeof(buf), MSG_DONTWAIT), 178 SyscallFailsWithErrno(EAGAIN)); 179 } 180 181 // Verifies that a UDP broadcast can be sent and then received back on the same 182 // socket that is bound to the broadcast address (255.255.255.255). 183 // FIXME(b/141938460): This can be combined with the next test 184 // (UDPBroadcastSendRecvOnSocketBoundToAny). 185 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 186 UDPBroadcastSendRecvOnSocketBoundToBroadcast) { 187 SKIP_IF(!found_net_interfaces_); 188 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 189 190 // Enable SO_BROADCAST. 191 ASSERT_THAT(setsockopt(sender->get(), SOL_SOCKET, SO_BROADCAST, &kSockOptOn, 192 sizeof(kSockOptOn)), 193 SyscallSucceedsWithValue(0)); 194 195 // Bind the sender to the broadcast address. 196 auto src_addr = V4Broadcast(); 197 ASSERT_THAT( 198 bind(sender->get(), AsSockAddr(&src_addr.addr), src_addr.addr_len), 199 SyscallSucceedsWithValue(0)); 200 socklen_t src_sz = src_addr.addr_len; 201 ASSERT_THAT(getsockname(sender->get(), AsSockAddr(&src_addr.addr), &src_sz), 202 SyscallSucceedsWithValue(0)); 203 EXPECT_EQ(src_sz, src_addr.addr_len); 204 205 // Send the message. 206 auto dst_addr = V4Broadcast(); 207 reinterpret_cast<sockaddr_in*>(&dst_addr.addr)->sin_port = 208 reinterpret_cast<sockaddr_in*>(&src_addr.addr)->sin_port; 209 constexpr char kTestMsg[] = "hello, world"; 210 EXPECT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, 211 AsSockAddr(&dst_addr.addr), dst_addr.addr_len), 212 SyscallSucceedsWithValue(sizeof(kTestMsg))); 213 214 // Verify that the message was received. 215 char buf[sizeof(kTestMsg)] = {}; 216 EXPECT_THAT(RetryEINTR(recv)(sender->get(), buf, sizeof(buf), 0), 217 SyscallSucceedsWithValue(sizeof(kTestMsg))); 218 EXPECT_EQ(0, memcmp(buf, kTestMsg, sizeof(kTestMsg))); 219 } 220 221 // Verifies that a UDP broadcast can be sent and then received back on the same 222 // socket that is bound to the ANY address (0.0.0.0). 223 // FIXME(b/141938460): This can be combined with the previous test 224 // (UDPBroadcastSendRecvOnSocketBoundToBroadcast). 225 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 226 UDPBroadcastSendRecvOnSocketBoundToAny) { 227 SKIP_IF(!found_net_interfaces_); 228 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 229 230 // Enable SO_BROADCAST. 231 ASSERT_THAT(setsockopt(sender->get(), SOL_SOCKET, SO_BROADCAST, &kSockOptOn, 232 sizeof(kSockOptOn)), 233 SyscallSucceedsWithValue(0)); 234 235 // Bind the sender to the ANY address. 236 auto src_addr = V4Any(); 237 ASSERT_THAT( 238 bind(sender->get(), AsSockAddr(&src_addr.addr), src_addr.addr_len), 239 SyscallSucceedsWithValue(0)); 240 socklen_t src_sz = src_addr.addr_len; 241 ASSERT_THAT(getsockname(sender->get(), AsSockAddr(&src_addr.addr), &src_sz), 242 SyscallSucceedsWithValue(0)); 243 EXPECT_EQ(src_sz, src_addr.addr_len); 244 245 // Send the message. 246 auto dst_addr = V4Broadcast(); 247 reinterpret_cast<sockaddr_in*>(&dst_addr.addr)->sin_port = 248 reinterpret_cast<sockaddr_in*>(&src_addr.addr)->sin_port; 249 constexpr char kTestMsg[] = "hello, world"; 250 EXPECT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, 251 AsSockAddr(&dst_addr.addr), dst_addr.addr_len), 252 SyscallSucceedsWithValue(sizeof(kTestMsg))); 253 254 // Verify that the message was received. 255 char buf[sizeof(kTestMsg)] = {}; 256 EXPECT_THAT(RetryEINTR(recv)(sender->get(), buf, sizeof(buf), 0), 257 SyscallSucceedsWithValue(sizeof(kTestMsg))); 258 EXPECT_EQ(0, memcmp(buf, kTestMsg, sizeof(kTestMsg))); 259 } 260 261 // Verifies that a UDP broadcast fails to send on a socket with SO_BROADCAST 262 // disabled. 263 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendBroadcast) { 264 SKIP_IF(!found_net_interfaces_); 265 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 266 267 // Broadcast a test message without having enabled SO_BROADCAST on the sending 268 // socket. 269 auto addr = V4Broadcast(); 270 reinterpret_cast<sockaddr_in*>(&addr.addr)->sin_port = htons(12345); 271 constexpr char kTestMsg[] = "hello, world"; 272 273 EXPECT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, 274 AsSockAddr(&addr.addr), addr.addr_len), 275 SyscallFailsWithErrno(EACCES)); 276 } 277 278 // Verifies that a UDP unicast on an unbound socket reaches its destination. 279 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendUnicastOnUnbound) { 280 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 281 auto rcvr = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 282 283 // Bind the receiver and retrieve its address and port number. 284 sockaddr_in addr = {}; 285 addr.sin_family = AF_INET; 286 addr.sin_addr.s_addr = htonl(INADDR_ANY); 287 addr.sin_port = htons(0); 288 ASSERT_THAT(bind(rcvr->get(), AsSockAddr(&addr), sizeof(addr)), 289 SyscallSucceedsWithValue(0)); 290 memset(&addr, 0, sizeof(addr)); 291 socklen_t addr_sz = sizeof(addr); 292 ASSERT_THAT(getsockname(rcvr->get(), AsSockAddr(&addr), &addr_sz), 293 SyscallSucceedsWithValue(0)); 294 295 // Send a test message to the receiver. 296 constexpr char kTestMsg[] = "hello, world"; 297 ASSERT_THAT(sendto(sender->get(), kTestMsg, sizeof(kTestMsg), 0, 298 AsSockAddr(&addr), addr_sz), 299 SyscallSucceedsWithValue(sizeof(kTestMsg))); 300 char buf[sizeof(kTestMsg)] = {}; 301 ASSERT_THAT(recv(rcvr->get(), buf, sizeof(buf), 0), 302 SyscallSucceedsWithValue(sizeof(kTestMsg))); 303 } 304 305 // Check that multicast packets won't be delivered to the sending socket with no 306 // set interface or group membership. 307 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 308 TestSendMulticastSelfNoGroup) { 309 // FIXME(b/125485338): A group membership is not required for external 310 // multicast on gVisor. 311 SKIP_IF(IsRunningOnGvisor()); 312 313 SKIP_IF(!found_net_interfaces_); 314 315 auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 316 317 auto bind_addr = V4Any(); 318 ASSERT_THAT( 319 bind(socket->get(), AsSockAddr(&bind_addr.addr), bind_addr.addr_len), 320 SyscallSucceeds()); 321 socklen_t bind_addr_len = bind_addr.addr_len; 322 ASSERT_THAT( 323 getsockname(socket->get(), AsSockAddr(&bind_addr.addr), &bind_addr_len), 324 SyscallSucceeds()); 325 EXPECT_EQ(bind_addr_len, bind_addr.addr_len); 326 327 // Send a multicast packet. 328 auto send_addr = V4Multicast(); 329 reinterpret_cast<sockaddr_in*>(&send_addr.addr)->sin_port = 330 reinterpret_cast<sockaddr_in*>(&bind_addr.addr)->sin_port; 331 char send_buf[200]; 332 RandomizeBuffer(send_buf, sizeof(send_buf)); 333 ASSERT_THAT( 334 RetryEINTR(sendto)(socket->get(), send_buf, sizeof(send_buf), 0, 335 AsSockAddr(&send_addr.addr), send_addr.addr_len), 336 SyscallSucceedsWithValue(sizeof(send_buf))); 337 338 // Check that we did not receive the multicast packet. 339 char recv_buf[sizeof(send_buf)] = {}; 340 ASSERT_THAT( 341 RetryEINTR(recv)(socket->get(), recv_buf, sizeof(recv_buf), MSG_DONTWAIT), 342 SyscallFailsWithErrno(EAGAIN)); 343 } 344 345 // Check that multicast packets will be delivered to the sending socket without 346 // setting an interface. 347 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticastSelf) { 348 SKIP_IF(!found_net_interfaces_); 349 auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 350 351 auto bind_addr = V4Any(); 352 ASSERT_THAT( 353 bind(socket->get(), AsSockAddr(&bind_addr.addr), bind_addr.addr_len), 354 SyscallSucceeds()); 355 socklen_t bind_addr_len = bind_addr.addr_len; 356 ASSERT_THAT( 357 getsockname(socket->get(), AsSockAddr(&bind_addr.addr), &bind_addr_len), 358 SyscallSucceeds()); 359 EXPECT_EQ(bind_addr_len, bind_addr.addr_len); 360 361 // Register to receive multicast packets. 362 ip_mreq group = {}; 363 group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); 364 ASSERT_THAT(setsockopt(socket->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, 365 sizeof(group)), 366 SyscallSucceeds()); 367 368 // Send a multicast packet. 369 auto send_addr = V4Multicast(); 370 reinterpret_cast<sockaddr_in*>(&send_addr.addr)->sin_port = 371 reinterpret_cast<sockaddr_in*>(&bind_addr.addr)->sin_port; 372 char send_buf[200]; 373 RandomizeBuffer(send_buf, sizeof(send_buf)); 374 ASSERT_THAT( 375 RetryEINTR(sendto)(socket->get(), send_buf, sizeof(send_buf), 0, 376 AsSockAddr(&send_addr.addr), send_addr.addr_len), 377 SyscallSucceedsWithValue(sizeof(send_buf))); 378 379 // Check that we received the multicast packet. 380 char recv_buf[sizeof(send_buf)] = {}; 381 ASSERT_THAT(RetryEINTR(recv)(socket->get(), recv_buf, sizeof(recv_buf), 0), 382 SyscallSucceedsWithValue(sizeof(recv_buf))); 383 384 EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); 385 } 386 387 // Check that multicast packets won't be delivered to the sending socket with no 388 // set interface and IP_MULTICAST_LOOP disabled. 389 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 390 TestSendMulticastSelfLoopOff) { 391 SKIP_IF(!found_net_interfaces_); 392 auto socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 393 394 auto bind_addr = V4Any(); 395 ASSERT_THAT( 396 bind(socket->get(), AsSockAddr(&bind_addr.addr), bind_addr.addr_len), 397 SyscallSucceeds()); 398 socklen_t bind_addr_len = bind_addr.addr_len; 399 ASSERT_THAT( 400 getsockname(socket->get(), AsSockAddr(&bind_addr.addr), &bind_addr_len), 401 SyscallSucceeds()); 402 EXPECT_EQ(bind_addr_len, bind_addr.addr_len); 403 404 // Disable multicast looping. 405 EXPECT_THAT(setsockopt(socket->get(), IPPROTO_IP, IP_MULTICAST_LOOP, 406 &kSockOptOff, sizeof(kSockOptOff)), 407 SyscallSucceeds()); 408 409 // Register to receive multicast packets. 410 ip_mreq group = {}; 411 group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); 412 EXPECT_THAT(setsockopt(socket->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, 413 sizeof(group)), 414 SyscallSucceeds()); 415 416 // Send a multicast packet. 417 auto send_addr = V4Multicast(); 418 reinterpret_cast<sockaddr_in*>(&send_addr.addr)->sin_port = 419 reinterpret_cast<sockaddr_in*>(&bind_addr.addr)->sin_port; 420 char send_buf[200]; 421 RandomizeBuffer(send_buf, sizeof(send_buf)); 422 ASSERT_THAT( 423 RetryEINTR(sendto)(socket->get(), send_buf, sizeof(send_buf), 0, 424 AsSockAddr(&send_addr.addr), send_addr.addr_len), 425 SyscallSucceedsWithValue(sizeof(send_buf))); 426 427 // Check that we did not receive the multicast packet. 428 char recv_buf[sizeof(send_buf)] = {}; 429 EXPECT_THAT( 430 RetryEINTR(recv)(socket->get(), recv_buf, sizeof(recv_buf), MSG_DONTWAIT), 431 SyscallFailsWithErrno(EAGAIN)); 432 } 433 434 // Check that multicast packets won't be delivered to another socket with no 435 // set interface or group membership. 436 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticastNoGroup) { 437 // FIXME(b/125485338): A group membership is not required for external 438 // multicast on gVisor. 439 SKIP_IF(IsRunningOnGvisor()); 440 441 SKIP_IF(!found_net_interfaces_); 442 443 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 444 auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 445 446 // Bind the second FD to the v4 any address to ensure that we can receive the 447 // multicast packet. 448 auto receiver_addr = V4Any(); 449 ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), 450 receiver_addr.addr_len), 451 SyscallSucceeds()); 452 socklen_t receiver_addr_len = receiver_addr.addr_len; 453 ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), 454 &receiver_addr_len), 455 SyscallSucceeds()); 456 EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); 457 458 // Send a multicast packet. 459 auto send_addr = V4Multicast(); 460 reinterpret_cast<sockaddr_in*>(&send_addr.addr)->sin_port = 461 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; 462 char send_buf[200]; 463 RandomizeBuffer(send_buf, sizeof(send_buf)); 464 ASSERT_THAT( 465 RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, 466 AsSockAddr(&send_addr.addr), send_addr.addr_len), 467 SyscallSucceedsWithValue(sizeof(send_buf))); 468 469 // Check that we did not receive the multicast packet. 470 char recv_buf[sizeof(send_buf)] = {}; 471 ASSERT_THAT(RetryEINTR(recv)(receiver->get(), recv_buf, sizeof(recv_buf), 472 MSG_DONTWAIT), 473 SyscallFailsWithErrno(EAGAIN)); 474 } 475 476 // Check that multicast packets will be delivered to another socket without 477 // setting an interface. 478 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, TestSendMulticast) { 479 SKIP_IF(!found_net_interfaces_); 480 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 481 auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 482 483 // Bind the second FD to the v4 any address to ensure that we can receive the 484 // multicast packet. 485 auto receiver_addr = V4Any(); 486 ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), 487 receiver_addr.addr_len), 488 SyscallSucceeds()); 489 socklen_t receiver_addr_len = receiver_addr.addr_len; 490 ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), 491 &receiver_addr_len), 492 SyscallSucceeds()); 493 EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); 494 495 // Register to receive multicast packets. 496 ip_mreqn group = {}; 497 group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); 498 ASSERT_THAT(setsockopt(receiver->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, 499 sizeof(group)), 500 SyscallSucceeds()); 501 502 // Send a multicast packet. 503 auto send_addr = V4Multicast(); 504 reinterpret_cast<sockaddr_in*>(&send_addr.addr)->sin_port = 505 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; 506 char send_buf[200]; 507 RandomizeBuffer(send_buf, sizeof(send_buf)); 508 ASSERT_THAT( 509 RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, 510 AsSockAddr(&send_addr.addr), send_addr.addr_len), 511 SyscallSucceedsWithValue(sizeof(send_buf))); 512 513 // Check that we received the multicast packet. 514 char recv_buf[sizeof(send_buf)] = {}; 515 ASSERT_THAT(RetryEINTR(recv)(receiver->get(), recv_buf, sizeof(recv_buf), 0), 516 SyscallSucceedsWithValue(sizeof(recv_buf))); 517 518 EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); 519 } 520 521 // Check that multicast packets won't be delivered to another socket with no 522 // set interface and IP_MULTICAST_LOOP disabled on the sending socket. 523 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 524 TestSendMulticastSenderNoLoop) { 525 SKIP_IF(!found_net_interfaces_); 526 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 527 auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 528 529 // Bind the second FD to the v4 any address to ensure that we can receive the 530 // multicast packet. 531 auto receiver_addr = V4Any(); 532 ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), 533 receiver_addr.addr_len), 534 SyscallSucceeds()); 535 socklen_t receiver_addr_len = receiver_addr.addr_len; 536 ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), 537 &receiver_addr_len), 538 SyscallSucceeds()); 539 EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); 540 541 // Disable multicast looping on the sender. 542 EXPECT_THAT(setsockopt(sender->get(), IPPROTO_IP, IP_MULTICAST_LOOP, 543 &kSockOptOff, sizeof(kSockOptOff)), 544 SyscallSucceeds()); 545 546 // Register to receive multicast packets. 547 ip_mreqn group = {}; 548 group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); 549 EXPECT_THAT(setsockopt(receiver->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, 550 sizeof(group)), 551 SyscallSucceeds()); 552 553 // Send a multicast packet. 554 auto send_addr = V4Multicast(); 555 reinterpret_cast<sockaddr_in*>(&send_addr.addr)->sin_port = 556 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; 557 char send_buf[200]; 558 RandomizeBuffer(send_buf, sizeof(send_buf)); 559 ASSERT_THAT( 560 RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, 561 AsSockAddr(&send_addr.addr), send_addr.addr_len), 562 SyscallSucceedsWithValue(sizeof(send_buf))); 563 564 // Check that we did not receive the multicast packet. 565 char recv_buf[sizeof(send_buf)] = {}; 566 ASSERT_THAT(RetryEINTR(recv)(receiver->get(), recv_buf, sizeof(recv_buf), 567 MSG_DONTWAIT), 568 SyscallFailsWithErrno(EAGAIN)); 569 } 570 571 // Check that multicast packets will be delivered to the sending socket without 572 // setting an interface and IP_MULTICAST_LOOP disabled on the receiving socket. 573 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 574 TestSendMulticastReceiverNoLoop) { 575 SKIP_IF(!found_net_interfaces_); 576 577 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 578 auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 579 580 // Bind the second FD to the v4 any address to ensure that we can receive the 581 // multicast packet. 582 auto receiver_addr = V4Any(); 583 ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), 584 receiver_addr.addr_len), 585 SyscallSucceeds()); 586 socklen_t receiver_addr_len = receiver_addr.addr_len; 587 ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), 588 &receiver_addr_len), 589 SyscallSucceeds()); 590 EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); 591 592 // Disable multicast looping on the receiver. 593 ASSERT_THAT(setsockopt(receiver->get(), IPPROTO_IP, IP_MULTICAST_LOOP, 594 &kSockOptOff, sizeof(kSockOptOff)), 595 SyscallSucceeds()); 596 597 // Register to receive multicast packets. 598 ip_mreqn group = {}; 599 group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); 600 ASSERT_THAT(setsockopt(receiver->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, 601 sizeof(group)), 602 SyscallSucceeds()); 603 604 // Send a multicast packet. 605 auto send_addr = V4Multicast(); 606 reinterpret_cast<sockaddr_in*>(&send_addr.addr)->sin_port = 607 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; 608 char send_buf[200]; 609 RandomizeBuffer(send_buf, sizeof(send_buf)); 610 ASSERT_THAT( 611 RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, 612 AsSockAddr(&send_addr.addr), send_addr.addr_len), 613 SyscallSucceedsWithValue(sizeof(send_buf))); 614 615 // Check that we received the multicast packet. 616 char recv_buf[sizeof(send_buf)] = {}; 617 ASSERT_THAT(RetryEINTR(recv)(receiver->get(), recv_buf, sizeof(recv_buf), 0), 618 SyscallSucceedsWithValue(sizeof(recv_buf))); 619 620 EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); 621 } 622 623 // Check that two sockets can join the same multicast group at the same time, 624 // and both will receive data on it when bound to the ANY address. 625 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 626 TestSendMulticastToTwoBoundToAny) { 627 SKIP_IF(!found_net_interfaces_); 628 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 629 std::unique_ptr<FileDescriptor> receivers[2] = { 630 ASSERT_NO_ERRNO_AND_VALUE(NewSocket()), 631 ASSERT_NO_ERRNO_AND_VALUE(NewSocket())}; 632 633 ip_mreq group = {}; 634 group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); 635 auto receiver_addr = V4Any(); 636 int bound_port = 0; 637 for (auto& receiver : receivers) { 638 ASSERT_THAT(setsockopt(receiver->get(), SOL_SOCKET, SO_REUSEPORT, 639 &kSockOptOn, sizeof(kSockOptOn)), 640 SyscallSucceeds()); 641 // Bind to ANY to receive multicast packets. 642 ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), 643 receiver_addr.addr_len), 644 SyscallSucceeds()); 645 socklen_t receiver_addr_len = receiver_addr.addr_len; 646 ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), 647 &receiver_addr_len), 648 SyscallSucceeds()); 649 EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); 650 EXPECT_EQ( 651 htonl(INADDR_ANY), 652 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_addr.s_addr); 653 // On the first iteration, save the port we are bound to. On the second 654 // iteration, verify the port is the same as the one from the first 655 // iteration. In other words, both sockets listen on the same port. 656 if (bound_port == 0) { 657 bound_port = 658 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; 659 } else { 660 EXPECT_EQ(bound_port, 661 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port); 662 } 663 664 // Register to receive multicast packets. 665 ASSERT_THAT(setsockopt(receiver->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, 666 &group, sizeof(group)), 667 SyscallSucceeds()); 668 } 669 670 // Send a multicast packet to the group and verify both receivers get it. 671 auto send_addr = V4Multicast(); 672 reinterpret_cast<sockaddr_in*>(&send_addr.addr)->sin_port = bound_port; 673 char send_buf[200]; 674 RandomizeBuffer(send_buf, sizeof(send_buf)); 675 ASSERT_THAT( 676 RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, 677 AsSockAddr(&send_addr.addr), send_addr.addr_len), 678 SyscallSucceedsWithValue(sizeof(send_buf))); 679 for (auto& receiver : receivers) { 680 char recv_buf[sizeof(send_buf)] = {}; 681 ASSERT_THAT( 682 RetryEINTR(recv)(receiver->get(), recv_buf, sizeof(recv_buf), 0), 683 SyscallSucceedsWithValue(sizeof(recv_buf))); 684 EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); 685 } 686 } 687 688 // Check that two sockets can join the same multicast group at the same time, 689 // and both will receive data on it when bound to the multicast address. 690 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 691 TestSendMulticastToTwoBoundToMulticastAddress) { 692 SKIP_IF(!found_net_interfaces_); 693 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 694 std::unique_ptr<FileDescriptor> receivers[2] = { 695 ASSERT_NO_ERRNO_AND_VALUE(NewSocket()), 696 ASSERT_NO_ERRNO_AND_VALUE(NewSocket())}; 697 698 ip_mreq group = {}; 699 group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); 700 auto receiver_addr = V4Multicast(); 701 int bound_port = 0; 702 for (auto& receiver : receivers) { 703 ASSERT_THAT(setsockopt(receiver->get(), SOL_SOCKET, SO_REUSEPORT, 704 &kSockOptOn, sizeof(kSockOptOn)), 705 SyscallSucceeds()); 706 ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), 707 receiver_addr.addr_len), 708 SyscallSucceeds()); 709 socklen_t receiver_addr_len = receiver_addr.addr_len; 710 ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), 711 &receiver_addr_len), 712 SyscallSucceeds()); 713 EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); 714 EXPECT_EQ( 715 inet_addr(kMulticastAddress), 716 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_addr.s_addr); 717 // On the first iteration, save the port we are bound to. On the second 718 // iteration, verify the port is the same as the one from the first 719 // iteration. In other words, both sockets listen on the same port. 720 if (bound_port == 0) { 721 bound_port = 722 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; 723 } else { 724 EXPECT_EQ( 725 inet_addr(kMulticastAddress), 726 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_addr.s_addr); 727 EXPECT_EQ(bound_port, 728 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port); 729 } 730 731 // Register to receive multicast packets. 732 ASSERT_THAT(setsockopt(receiver->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, 733 &group, sizeof(group)), 734 SyscallSucceeds()); 735 } 736 737 // Send a multicast packet to the group and verify both receivers get it. 738 auto send_addr = V4Multicast(); 739 reinterpret_cast<sockaddr_in*>(&send_addr.addr)->sin_port = bound_port; 740 char send_buf[200]; 741 RandomizeBuffer(send_buf, sizeof(send_buf)); 742 ASSERT_THAT( 743 RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, 744 AsSockAddr(&send_addr.addr), send_addr.addr_len), 745 SyscallSucceedsWithValue(sizeof(send_buf))); 746 for (auto& receiver : receivers) { 747 char recv_buf[sizeof(send_buf)] = {}; 748 ASSERT_THAT( 749 RetryEINTR(recv)(receiver->get(), recv_buf, sizeof(recv_buf), 0), 750 SyscallSucceedsWithValue(sizeof(recv_buf))); 751 EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); 752 } 753 } 754 755 // Check that two sockets can join the same multicast group at the same time, 756 // and with one bound to the wildcard address and the other bound to the 757 // multicast address, both will receive data. 758 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 759 TestSendMulticastToTwoBoundToAnyAndMulticastAddress) { 760 SKIP_IF(!found_net_interfaces_); 761 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 762 std::unique_ptr<FileDescriptor> receivers[2] = { 763 ASSERT_NO_ERRNO_AND_VALUE(NewSocket()), 764 ASSERT_NO_ERRNO_AND_VALUE(NewSocket())}; 765 766 ip_mreq group = {}; 767 group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); 768 // The first receiver binds to the wildcard address. 769 auto receiver_addr = V4Any(); 770 int bound_port = 0; 771 for (auto& receiver : receivers) { 772 ASSERT_THAT(setsockopt(receiver->get(), SOL_SOCKET, SO_REUSEPORT, 773 &kSockOptOn, sizeof(kSockOptOn)), 774 SyscallSucceeds()); 775 ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), 776 receiver_addr.addr_len), 777 SyscallSucceeds()); 778 socklen_t receiver_addr_len = receiver_addr.addr_len; 779 ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), 780 &receiver_addr_len), 781 SyscallSucceeds()); 782 EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); 783 // On the first iteration, save the port we are bound to and change the 784 // receiver address from V4Any to V4Multicast so the second receiver binds 785 // to that. On the second iteration, verify the port is the same as the one 786 // from the first iteration but the address is different. 787 if (bound_port == 0) { 788 EXPECT_EQ( 789 htonl(INADDR_ANY), 790 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_addr.s_addr); 791 bound_port = 792 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; 793 receiver_addr = V4Multicast(); 794 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port = 795 bound_port; 796 } else { 797 EXPECT_EQ( 798 inet_addr(kMulticastAddress), 799 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_addr.s_addr); 800 EXPECT_EQ(bound_port, 801 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port); 802 } 803 804 // Register to receive multicast packets. 805 ASSERT_THAT(setsockopt(receiver->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, 806 &group, sizeof(group)), 807 SyscallSucceeds()); 808 } 809 810 // Send a multicast packet to the group and verify both receivers get it. 811 auto send_addr = V4Multicast(); 812 reinterpret_cast<sockaddr_in*>(&send_addr.addr)->sin_port = bound_port; 813 char send_buf[200]; 814 RandomizeBuffer(send_buf, sizeof(send_buf)); 815 ASSERT_THAT( 816 RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, 817 AsSockAddr(&send_addr.addr), send_addr.addr_len), 818 SyscallSucceedsWithValue(sizeof(send_buf))); 819 for (auto& receiver : receivers) { 820 char recv_buf[sizeof(send_buf)] = {}; 821 ASSERT_THAT( 822 RetryEINTR(recv)(receiver->get(), recv_buf, sizeof(recv_buf), 0), 823 SyscallSucceedsWithValue(sizeof(recv_buf))); 824 EXPECT_EQ(0, memcmp(send_buf, recv_buf, sizeof(send_buf))); 825 } 826 } 827 828 // Check that when receiving a looped-back multicast packet, its source address 829 // is not a multicast address. 830 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 831 IpMulticastLoopbackFromAddr) { 832 SKIP_IF(!found_net_interfaces_); 833 834 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 835 auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 836 837 auto receiver_addr = V4Any(); 838 ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), 839 receiver_addr.addr_len), 840 SyscallSucceeds()); 841 socklen_t receiver_addr_len = receiver_addr.addr_len; 842 ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), 843 &receiver_addr_len), 844 SyscallSucceeds()); 845 EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); 846 int receiver_port = 847 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; 848 849 ip_mreq group = {}; 850 group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); 851 ASSERT_THAT(setsockopt(receiver->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, 852 sizeof(group)), 853 SyscallSucceeds()); 854 855 // Connect to the multicast address. This binds us to the outgoing interface 856 // and allows us to get its IP (to be compared against the src-IP on the 857 // receiver side). 858 auto sendto_addr = V4Multicast(); 859 reinterpret_cast<sockaddr_in*>(&sendto_addr.addr)->sin_port = receiver_port; 860 ASSERT_THAT(RetryEINTR(connect)(sender->get(), AsSockAddr(&sendto_addr.addr), 861 sendto_addr.addr_len), 862 SyscallSucceeds()); 863 auto sender_addr = V4EmptyAddress(); 864 ASSERT_THAT(getsockname(sender->get(), AsSockAddr(&sender_addr.addr), 865 &sender_addr.addr_len), 866 SyscallSucceeds()); 867 ASSERT_EQ(sizeof(struct sockaddr_in), sender_addr.addr_len); 868 sockaddr_in* sender_addr_in = 869 reinterpret_cast<sockaddr_in*>(&sender_addr.addr); 870 871 // Send a multicast packet. 872 char send_buf[4] = {}; 873 ASSERT_THAT(RetryEINTR(send)(sender->get(), send_buf, sizeof(send_buf), 0), 874 SyscallSucceedsWithValue(sizeof(send_buf))); 875 876 // Receive a multicast packet. 877 char recv_buf[sizeof(send_buf)] = {}; 878 auto src_addr = V4EmptyAddress(); 879 ASSERT_THAT( 880 RetryEINTR(recvfrom)(receiver->get(), recv_buf, sizeof(recv_buf), 0, 881 AsSockAddr(&src_addr.addr), &src_addr.addr_len), 882 SyscallSucceedsWithValue(sizeof(recv_buf))); 883 ASSERT_EQ(sizeof(struct sockaddr_in), src_addr.addr_len); 884 sockaddr_in* src_addr_in = reinterpret_cast<sockaddr_in*>(&src_addr.addr); 885 886 // Verify that the received source IP:port matches the sender one. 887 EXPECT_EQ(sender_addr_in->sin_port, src_addr_in->sin_port); 888 EXPECT_EQ(sender_addr_in->sin_addr.s_addr, src_addr_in->sin_addr.s_addr); 889 } 890 891 // Check that when setting the IP_MULTICAST_IF option to both an index pointing 892 // to the loopback interface and an address pointing to the non-loopback 893 // interface, a multicast packet sent out uses the latter as its source address. 894 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 895 IpMulticastLoopbackIfNicAndAddr) { 896 SKIP_IF(!found_net_interfaces_); 897 898 // Create receiver, bind to ANY and join the multicast group. 899 auto receiver = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 900 auto receiver_addr = V4Any(); 901 ASSERT_THAT(bind(receiver->get(), AsSockAddr(&receiver_addr.addr), 902 receiver_addr.addr_len), 903 SyscallSucceeds()); 904 socklen_t receiver_addr_len = receiver_addr.addr_len; 905 ASSERT_THAT(getsockname(receiver->get(), AsSockAddr(&receiver_addr.addr), 906 &receiver_addr_len), 907 SyscallSucceeds()); 908 EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len); 909 int receiver_port = 910 reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)->sin_port; 911 ip_mreqn group = {}; 912 group.imr_multiaddr.s_addr = inet_addr(kMulticastAddress); 913 group.imr_ifindex = lo_if_idx_; 914 ASSERT_THAT(setsockopt(receiver->get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, 915 sizeof(group)), 916 SyscallSucceeds()); 917 918 // Set outgoing multicast interface config, with NIC and addr pointing to 919 // different interfaces. 920 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 921 ip_mreqn iface = {}; 922 iface.imr_ifindex = lo_if_idx_; 923 iface.imr_address = eth_if_addr_.sin_addr; 924 ASSERT_THAT(setsockopt(sender->get(), IPPROTO_IP, IP_MULTICAST_IF, &iface, 925 sizeof(iface)), 926 SyscallSucceeds()); 927 928 // Send a multicast packet. 929 auto sendto_addr = V4Multicast(); 930 reinterpret_cast<sockaddr_in*>(&sendto_addr.addr)->sin_port = receiver_port; 931 char send_buf[4] = {}; 932 ASSERT_THAT( 933 RetryEINTR(sendto)(sender->get(), send_buf, sizeof(send_buf), 0, 934 AsSockAddr(&sendto_addr.addr), sendto_addr.addr_len), 935 SyscallSucceedsWithValue(sizeof(send_buf))); 936 937 // Receive a multicast packet. 938 char recv_buf[sizeof(send_buf)] = {}; 939 auto src_addr = V4EmptyAddress(); 940 ASSERT_THAT( 941 RetryEINTR(recvfrom)(receiver->get(), recv_buf, sizeof(recv_buf), 0, 942 AsSockAddr(&src_addr.addr), &src_addr.addr_len), 943 SyscallSucceedsWithValue(sizeof(recv_buf))); 944 ASSERT_EQ(sizeof(struct sockaddr_in), src_addr.addr_len); 945 sockaddr_in* src_addr_in = reinterpret_cast<sockaddr_in*>(&src_addr.addr); 946 947 // FIXME (b/137781162): When sending a multicast packet use the proper logic 948 // to determine the packet's src-IP. 949 SKIP_IF(IsRunningOnGvisor()); 950 951 // Verify the received source address. 952 EXPECT_EQ(eth_if_addr_.sin_addr.s_addr, src_addr_in->sin_addr.s_addr); 953 } 954 955 // Check that when we are bound to one interface we can set IP_MULTICAST_IF to 956 // another interface. 957 TEST_P(IPv4UDPUnboundExternalNetworkingSocketTest, 958 IpMulticastLoopbackBindToOneIfSetMcastIfToAnother) { 959 SKIP_IF(!found_net_interfaces_); 960 961 // FIXME (b/137790511): When bound to one interface it is not possible to set 962 // IP_MULTICAST_IF to a different interface. 963 SKIP_IF(IsRunningOnGvisor()); 964 965 // Create sender and bind to eth interface. 966 auto sender = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); 967 ASSERT_THAT( 968 bind(sender->get(), AsSockAddr(ð_if_addr_), sizeof(eth_if_addr_)), 969 SyscallSucceeds()); 970 971 // Run through all possible combinations of index and address for 972 // IP_MULTICAST_IF that selects the loopback interface. 973 struct { 974 int imr_ifindex; 975 struct in_addr imr_address; 976 } test_data[] = { 977 {lo_if_idx_, {}}, 978 {0, lo_if_addr_.sin_addr}, 979 {lo_if_idx_, lo_if_addr_.sin_addr}, 980 {lo_if_idx_, eth_if_addr_.sin_addr}, 981 }; 982 for (auto t : test_data) { 983 ip_mreqn iface = {}; 984 iface.imr_ifindex = t.imr_ifindex; 985 iface.imr_address = t.imr_address; 986 EXPECT_THAT(setsockopt(sender->get(), IPPROTO_IP, IP_MULTICAST_IF, &iface, 987 sizeof(iface)), 988 SyscallSucceeds()) 989 << "imr_index=" << iface.imr_ifindex 990 << " imr_address=" << GetAddr4Str(&iface.imr_address); 991 } 992 } 993 } // namespace testing 994 } // namespace gvisor