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(&eth_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