• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/udp/udp_client_socket.h"
6 #include "net/udp/udp_server_socket.h"
7 
8 #include "base/basictypes.h"
9 #include "base/bind.h"
10 #include "base/metrics/histogram.h"
11 #include "base/stl_util.h"
12 #include "net/base/io_buffer.h"
13 #include "net/base/ip_endpoint.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/net_log_unittest.h"
16 #include "net/base/net_util.h"
17 #include "net/base/test_completion_callback.h"
18 #include "net/test/net_test_suite.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "testing/platform_test.h"
21 
22 namespace net {
23 
24 namespace {
25 
26 class UDPSocketTest : public PlatformTest {
27  public:
UDPSocketTest()28   UDPSocketTest()
29       : buffer_(new IOBufferWithSize(kMaxRead)) {
30   }
31 
32   // Blocks until data is read from the socket.
RecvFromSocket(UDPServerSocket * socket)33   std::string RecvFromSocket(UDPServerSocket* socket) {
34     TestCompletionCallback callback;
35 
36     int rv = socket->RecvFrom(
37         buffer_.get(), kMaxRead, &recv_from_address_, callback.callback());
38     if (rv == ERR_IO_PENDING)
39       rv = callback.WaitForResult();
40     if (rv < 0)
41       return std::string();  // error!
42     return std::string(buffer_->data(), rv);
43   }
44 
45   // Loop until |msg| has been written to the socket or until an
46   // error occurs.
47   // If |address| is specified, then it is used for the destination
48   // to send to. Otherwise, will send to the last socket this server
49   // received from.
SendToSocket(UDPServerSocket * socket,std::string msg)50   int SendToSocket(UDPServerSocket* socket, std::string msg) {
51     return SendToSocket(socket, msg, recv_from_address_);
52   }
53 
SendToSocket(UDPServerSocket * socket,std::string msg,const IPEndPoint & address)54   int SendToSocket(UDPServerSocket* socket,
55                    std::string msg,
56                    const IPEndPoint& address) {
57     TestCompletionCallback callback;
58 
59     int length = msg.length();
60     scoped_refptr<StringIOBuffer> io_buffer(new StringIOBuffer(msg));
61     scoped_refptr<DrainableIOBuffer> buffer(
62         new DrainableIOBuffer(io_buffer.get(), length));
63 
64     int bytes_sent = 0;
65     while (buffer->BytesRemaining()) {
66       int rv = socket->SendTo(
67           buffer.get(), buffer->BytesRemaining(), address, callback.callback());
68       if (rv == ERR_IO_PENDING)
69         rv = callback.WaitForResult();
70       if (rv <= 0)
71         return bytes_sent > 0 ? bytes_sent : rv;
72       bytes_sent += rv;
73       buffer->DidConsume(rv);
74     }
75     return bytes_sent;
76   }
77 
ReadSocket(UDPClientSocket * socket)78   std::string ReadSocket(UDPClientSocket* socket) {
79     TestCompletionCallback callback;
80 
81     int rv = socket->Read(buffer_.get(), kMaxRead, callback.callback());
82     if (rv == ERR_IO_PENDING)
83       rv = callback.WaitForResult();
84     if (rv < 0)
85       return std::string();  // error!
86     return std::string(buffer_->data(), rv);
87   }
88 
89   // Loop until |msg| has been written to the socket or until an
90   // error occurs.
WriteSocket(UDPClientSocket * socket,std::string msg)91   int WriteSocket(UDPClientSocket* socket, std::string msg) {
92     TestCompletionCallback callback;
93 
94     int length = msg.length();
95     scoped_refptr<StringIOBuffer> io_buffer(new StringIOBuffer(msg));
96     scoped_refptr<DrainableIOBuffer> buffer(
97         new DrainableIOBuffer(io_buffer.get(), length));
98 
99     int bytes_sent = 0;
100     while (buffer->BytesRemaining()) {
101       int rv = socket->Write(
102           buffer.get(), buffer->BytesRemaining(), callback.callback());
103       if (rv == ERR_IO_PENDING)
104         rv = callback.WaitForResult();
105       if (rv <= 0)
106         return bytes_sent > 0 ? bytes_sent : rv;
107       bytes_sent += rv;
108       buffer->DidConsume(rv);
109     }
110     return bytes_sent;
111   }
112 
113  protected:
114   static const int kMaxRead = 1024;
115   scoped_refptr<IOBufferWithSize> buffer_;
116   IPEndPoint recv_from_address_;
117 };
118 
119 // Creates and address from an ip/port and returns it in |address|.
CreateUDPAddress(std::string ip_str,int port,IPEndPoint * address)120 void CreateUDPAddress(std::string ip_str, int port, IPEndPoint* address) {
121   IPAddressNumber ip_number;
122   bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
123   if (!rv)
124     return;
125   *address = IPEndPoint(ip_number, port);
126 }
127 
TEST_F(UDPSocketTest,Connect)128 TEST_F(UDPSocketTest, Connect) {
129   const int kPort = 9999;
130   std::string simple_message("hello world!");
131 
132   // Setup the server to listen.
133   IPEndPoint bind_address;
134   CreateUDPAddress("127.0.0.1", kPort, &bind_address);
135   CapturingNetLog server_log;
136   scoped_ptr<UDPServerSocket> server(
137       new UDPServerSocket(&server_log, NetLog::Source()));
138   server->AllowAddressReuse();
139   int rv = server->Listen(bind_address);
140   ASSERT_EQ(OK, rv);
141 
142   // Setup the client.
143   IPEndPoint server_address;
144   CreateUDPAddress("127.0.0.1", kPort, &server_address);
145   CapturingNetLog client_log;
146   scoped_ptr<UDPClientSocket> client(
147       new UDPClientSocket(DatagramSocket::DEFAULT_BIND,
148                           RandIntCallback(),
149                           &client_log,
150                           NetLog::Source()));
151   rv = client->Connect(server_address);
152   EXPECT_EQ(OK, rv);
153 
154   // Client sends to the server.
155   rv = WriteSocket(client.get(), simple_message);
156   EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
157 
158   // Server waits for message.
159   std::string str = RecvFromSocket(server.get());
160   DCHECK(simple_message == str);
161 
162   // Server echoes reply.
163   rv = SendToSocket(server.get(), simple_message);
164   EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
165 
166   // Client waits for response.
167   str = ReadSocket(client.get());
168   DCHECK(simple_message == str);
169 
170   // Delete sockets so they log their final events.
171   server.reset();
172   client.reset();
173 
174   // Check the server's log.
175   CapturingNetLog::CapturedEntryList server_entries;
176   server_log.GetEntries(&server_entries);
177   EXPECT_EQ(4u, server_entries.size());
178   EXPECT_TRUE(LogContainsBeginEvent(
179       server_entries, 0, NetLog::TYPE_SOCKET_ALIVE));
180   EXPECT_TRUE(LogContainsEvent(
181       server_entries, 1, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE));
182   EXPECT_TRUE(LogContainsEvent(
183       server_entries, 2, NetLog::TYPE_UDP_BYTES_SENT, NetLog::PHASE_NONE));
184   EXPECT_TRUE(LogContainsEndEvent(
185       server_entries, 3, NetLog::TYPE_SOCKET_ALIVE));
186 
187   // Check the client's log.
188   CapturingNetLog::CapturedEntryList client_entries;
189   client_log.GetEntries(&client_entries);
190   EXPECT_EQ(6u, client_entries.size());
191   EXPECT_TRUE(LogContainsBeginEvent(
192       client_entries, 0, NetLog::TYPE_SOCKET_ALIVE));
193   EXPECT_TRUE(LogContainsBeginEvent(
194       client_entries, 1, NetLog::TYPE_UDP_CONNECT));
195   EXPECT_TRUE(LogContainsEndEvent(
196       client_entries, 2, NetLog::TYPE_UDP_CONNECT));
197   EXPECT_TRUE(LogContainsEvent(
198       client_entries, 3, NetLog::TYPE_UDP_BYTES_SENT, NetLog::PHASE_NONE));
199   EXPECT_TRUE(LogContainsEvent(
200       client_entries, 4, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE));
201   EXPECT_TRUE(LogContainsEndEvent(
202       client_entries, 5, NetLog::TYPE_SOCKET_ALIVE));
203 }
204 
205 #if defined(OS_MACOSX)
206 // UDPSocketPrivate_Broadcast is disabled for OSX because it requires
207 // root permissions on OSX 10.7+.
TEST_F(UDPSocketTest,DISABLED_Broadcast)208 TEST_F(UDPSocketTest, DISABLED_Broadcast) {
209 #elif defined(OS_ANDROID)
210 // It is also disabled for Android because it is extremely flaky.
211 // The first call to SendToSocket returns -109 (Address not reachable)
212 // in some unpredictable cases. crbug.com/139144.
213 TEST_F(UDPSocketTest, DISABLED_Broadcast) {
214 #else
215 TEST_F(UDPSocketTest, Broadcast) {
216 #endif
217   const int kPort = 9999;
218   std::string first_message("first message"), second_message("second message");
219 
220   IPEndPoint broadcast_address;
221   CreateUDPAddress("255.255.255.255", kPort, &broadcast_address);
222   IPEndPoint listen_address;
223   CreateUDPAddress("0.0.0.0", kPort, &listen_address);
224 
225   CapturingNetLog server1_log, server2_log;
226   scoped_ptr<UDPServerSocket> server1(
227       new UDPServerSocket(&server1_log, NetLog::Source()));
228   scoped_ptr<UDPServerSocket> server2(
229       new UDPServerSocket(&server2_log, NetLog::Source()));
230   server1->AllowAddressReuse();
231   server1->AllowBroadcast();
232   server2->AllowAddressReuse();
233   server2->AllowBroadcast();
234 
235   int rv = server1->Listen(listen_address);
236   EXPECT_EQ(OK, rv);
237   rv = server2->Listen(listen_address);
238   EXPECT_EQ(OK, rv);
239 
240   rv = SendToSocket(server1.get(), first_message, broadcast_address);
241   ASSERT_EQ(static_cast<int>(first_message.size()), rv);
242   std::string str = RecvFromSocket(server1.get());
243   ASSERT_EQ(first_message, str);
244   str = RecvFromSocket(server2.get());
245   ASSERT_EQ(first_message, str);
246 
247   rv = SendToSocket(server2.get(), second_message, broadcast_address);
248   ASSERT_EQ(static_cast<int>(second_message.size()), rv);
249   str = RecvFromSocket(server1.get());
250   ASSERT_EQ(second_message, str);
251   str = RecvFromSocket(server2.get());
252   ASSERT_EQ(second_message, str);
253 }
254 
255 // In this test, we verify that random binding logic works, which attempts
256 // to bind to a random port and returns if succeeds, otherwise retries for
257 // |kBindRetries| number of times.
258 
259 // To generate the scenario, we first create |kBindRetries| number of
260 // UDPClientSockets with default binding policy and connect to the same
261 // peer and save the used port numbers.  Then we get rid of the last
262 // socket, making sure that the local port it was bound to is available.
263 // Finally, we create a socket with random binding policy, passing it a
264 // test PRNG that would serve used port numbers in the array, one after
265 // another.  At the end, we make sure that the test socket was bound to the
266 // port that became available after deleting the last socket with default
267 // binding policy.
268 
269 // We do not test the randomness of bound ports, but that we are using
270 // passed in PRNG correctly, thus, it's the duty of PRNG to produce strong
271 // random numbers.
272 static const int kBindRetries = 10;
273 
274 class TestPrng {
275  public:
276   explicit TestPrng(const std::deque<int>& numbers) : numbers_(numbers) {}
277   int GetNext(int /* min */, int /* max */) {
278     DCHECK(!numbers_.empty());
279     int rv = numbers_.front();
280     numbers_.pop_front();
281     return rv;
282   }
283  private:
284   std::deque<int> numbers_;
285 
286   DISALLOW_COPY_AND_ASSIGN(TestPrng);
287 };
288 
289 #if defined(OS_ANDROID)
290 // Disabled on Android for lack of 192.168.1.13. crbug.com/161245
291 TEST_F(UDPSocketTest, DISABLED_ConnectRandomBind) {
292 #else
293 TEST_F(UDPSocketTest, ConnectRandomBind) {
294 #endif
295   std::vector<UDPClientSocket*> sockets;
296   IPEndPoint peer_address;
297   CreateUDPAddress("192.168.1.13", 53, &peer_address);
298 
299   // Create and connect sockets and save port numbers.
300   std::deque<int> used_ports;
301   for (int i = 0; i < kBindRetries; ++i) {
302     UDPClientSocket* socket =
303         new UDPClientSocket(DatagramSocket::DEFAULT_BIND,
304                             RandIntCallback(),
305                             NULL,
306                             NetLog::Source());
307     sockets.push_back(socket);
308     EXPECT_EQ(OK, socket->Connect(peer_address));
309 
310     IPEndPoint client_address;
311     EXPECT_EQ(OK, socket->GetLocalAddress(&client_address));
312     used_ports.push_back(client_address.port());
313   }
314 
315   // Free the last socket, its local port is still in |used_ports|.
316   delete sockets.back();
317   sockets.pop_back();
318 
319   TestPrng test_prng(used_ports);
320   RandIntCallback rand_int_cb =
321       base::Bind(&TestPrng::GetNext, base::Unretained(&test_prng));
322 
323   // Create a socket with random binding policy and connect.
324   scoped_ptr<UDPClientSocket> test_socket(
325       new UDPClientSocket(DatagramSocket::RANDOM_BIND,
326                           rand_int_cb,
327                           NULL,
328                           NetLog::Source()));
329   EXPECT_EQ(OK, test_socket->Connect(peer_address));
330 
331   // Make sure that the last port number in the |used_ports| was used.
332   IPEndPoint client_address;
333   EXPECT_EQ(OK, test_socket->GetLocalAddress(&client_address));
334   EXPECT_EQ(used_ports.back(), client_address.port());
335 
336   STLDeleteElements(&sockets);
337 }
338 
339 // Return a privileged port (under 1024) so binding will fail.
340 int PrivilegedRand(int min, int max) {
341   // Chosen by fair dice roll.  Guaranteed to be random.
342   return 4;
343 }
344 
345 TEST_F(UDPSocketTest, ConnectFail) {
346   IPEndPoint peer_address;
347   CreateUDPAddress("0.0.0.0", 53, &peer_address);
348 
349   scoped_ptr<UDPSocket> socket(
350       new UDPSocket(DatagramSocket::RANDOM_BIND,
351                     base::Bind(&PrivilegedRand),
352                     NULL,
353                     NetLog::Source()));
354   int rv = socket->Connect(peer_address);
355   // Connect should have failed since we couldn't bind to that port,
356   EXPECT_NE(OK, rv);
357   // Make sure that UDPSocket actually closed the socket.
358   EXPECT_FALSE(socket->is_connected());
359 }
360 
361 // In this test, we verify that connect() on a socket will have the effect
362 // of filtering reads on this socket only to data read from the destination
363 // we connected to.
364 //
365 // The purpose of this test is that some documentation indicates that connect
366 // binds the client's sends to send to a particular server endpoint, but does
367 // not bind the client's reads to only be from that endpoint, and that we need
368 // to always use recvfrom() to disambiguate.
369 TEST_F(UDPSocketTest, VerifyConnectBindsAddr) {
370   const int kPort1 = 9999;
371   const int kPort2 = 10000;
372   std::string simple_message("hello world!");
373   std::string foreign_message("BAD MESSAGE TO GET!!");
374 
375   // Setup the first server to listen.
376   IPEndPoint bind_address;
377   CreateUDPAddress("127.0.0.1", kPort1, &bind_address);
378   UDPServerSocket server1(NULL, NetLog::Source());
379   server1.AllowAddressReuse();
380   int rv = server1.Listen(bind_address);
381   ASSERT_EQ(OK, rv);
382 
383   // Setup the second server to listen.
384   CreateUDPAddress("127.0.0.1", kPort2, &bind_address);
385   UDPServerSocket server2(NULL, NetLog::Source());
386   server2.AllowAddressReuse();
387   rv = server2.Listen(bind_address);
388   ASSERT_EQ(OK, rv);
389 
390   // Setup the client, connected to server 1.
391   IPEndPoint server_address;
392   CreateUDPAddress("127.0.0.1", kPort1, &server_address);
393   UDPClientSocket client(DatagramSocket::DEFAULT_BIND,
394                          RandIntCallback(),
395                          NULL,
396                          NetLog::Source());
397   rv = client.Connect(server_address);
398   EXPECT_EQ(OK, rv);
399 
400   // Client sends to server1.
401   rv = WriteSocket(&client, simple_message);
402   EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
403 
404   // Server1 waits for message.
405   std::string str = RecvFromSocket(&server1);
406   DCHECK(simple_message == str);
407 
408   // Get the client's address.
409   IPEndPoint client_address;
410   rv = client.GetLocalAddress(&client_address);
411   EXPECT_EQ(OK, rv);
412 
413   // Server2 sends reply.
414   rv = SendToSocket(&server2, foreign_message,
415                     client_address);
416   EXPECT_EQ(foreign_message.length(), static_cast<size_t>(rv));
417 
418   // Server1 sends reply.
419   rv = SendToSocket(&server1, simple_message,
420                     client_address);
421   EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
422 
423   // Client waits for response.
424   str = ReadSocket(&client);
425   DCHECK(simple_message == str);
426 }
427 
428 TEST_F(UDPSocketTest, ClientGetLocalPeerAddresses) {
429   struct TestData {
430     std::string remote_address;
431     std::string local_address;
432     bool may_fail;
433   } tests[] = {
434     { "127.0.00.1", "127.0.0.1", false },
435     { "::1", "::1", true },
436 #if !defined(OS_ANDROID)
437     // Addresses below are disabled on Android. See crbug.com/161248
438     { "192.168.1.1", "127.0.0.1", false },
439     { "2001:db8:0::42", "::1", true },
440 #endif
441   };
442   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); i++) {
443     SCOPED_TRACE(std::string("Connecting from ") +  tests[i].local_address +
444                  std::string(" to ") + tests[i].remote_address);
445 
446     IPAddressNumber ip_number;
447     ParseIPLiteralToNumber(tests[i].remote_address, &ip_number);
448     IPEndPoint remote_address(ip_number, 80);
449     ParseIPLiteralToNumber(tests[i].local_address, &ip_number);
450     IPEndPoint local_address(ip_number, 80);
451 
452     UDPClientSocket client(DatagramSocket::DEFAULT_BIND,
453                            RandIntCallback(),
454                            NULL,
455                            NetLog::Source());
456     int rv = client.Connect(remote_address);
457     if (tests[i].may_fail && rv == ERR_ADDRESS_UNREACHABLE) {
458       // Connect() may return ERR_ADDRESS_UNREACHABLE for IPv6
459       // addresses if IPv6 is not configured.
460       continue;
461     }
462 
463     EXPECT_LE(ERR_IO_PENDING, rv);
464 
465     IPEndPoint fetched_local_address;
466     rv = client.GetLocalAddress(&fetched_local_address);
467     EXPECT_EQ(OK, rv);
468 
469     // TODO(mbelshe): figure out how to verify the IP and port.
470     //                The port is dynamically generated by the udp stack.
471     //                The IP is the real IP of the client, not necessarily
472     //                loopback.
473     //EXPECT_EQ(local_address.address(), fetched_local_address.address());
474 
475     IPEndPoint fetched_remote_address;
476     rv = client.GetPeerAddress(&fetched_remote_address);
477     EXPECT_EQ(OK, rv);
478 
479     EXPECT_EQ(remote_address, fetched_remote_address);
480   }
481 }
482 
483 TEST_F(UDPSocketTest, ServerGetLocalAddress) {
484   IPEndPoint bind_address;
485   CreateUDPAddress("127.0.0.1", 0, &bind_address);
486   UDPServerSocket server(NULL, NetLog::Source());
487   int rv = server.Listen(bind_address);
488   EXPECT_EQ(OK, rv);
489 
490   IPEndPoint local_address;
491   rv = server.GetLocalAddress(&local_address);
492   EXPECT_EQ(rv, 0);
493 
494   // Verify that port was allocated.
495   EXPECT_GT(local_address.port(), 0);
496   EXPECT_EQ(local_address.address(), bind_address.address());
497 }
498 
499 TEST_F(UDPSocketTest, ServerGetPeerAddress) {
500   IPEndPoint bind_address;
501   CreateUDPAddress("127.0.0.1", 0, &bind_address);
502   UDPServerSocket server(NULL, NetLog::Source());
503   int rv = server.Listen(bind_address);
504   EXPECT_EQ(OK, rv);
505 
506   IPEndPoint peer_address;
507   rv = server.GetPeerAddress(&peer_address);
508   EXPECT_EQ(rv, ERR_SOCKET_NOT_CONNECTED);
509 }
510 
511 // Close the socket while read is pending.
512 TEST_F(UDPSocketTest, CloseWithPendingRead) {
513   IPEndPoint bind_address;
514   CreateUDPAddress("127.0.0.1", 0, &bind_address);
515   UDPServerSocket server(NULL, NetLog::Source());
516   int rv = server.Listen(bind_address);
517   EXPECT_EQ(OK, rv);
518 
519   TestCompletionCallback callback;
520   IPEndPoint from;
521   rv = server.RecvFrom(buffer_.get(), kMaxRead, &from, callback.callback());
522   EXPECT_EQ(rv, ERR_IO_PENDING);
523 
524   server.Close();
525 
526   EXPECT_FALSE(callback.have_result());
527 }
528 
529 #if defined(OS_ANDROID)
530 // Some Android devices do not support multicast socket.
531 // The ones supporting multicast need WifiManager.MulitcastLock to enable it.
532 // http://goo.gl/jjAk9
533 #define MAYBE_JoinMulticastGroup DISABLED_JoinMulticastGroup
534 #else
535 #define MAYBE_JoinMulticastGroup JoinMulticastGroup
536 #endif  // defined(OS_ANDROID)
537 
538 TEST_F(UDPSocketTest, MAYBE_JoinMulticastGroup) {
539   const int kPort = 9999;
540   const char* const kGroup = "237.132.100.17";
541 
542   IPEndPoint bind_address;
543   CreateUDPAddress("0.0.0.0", kPort, &bind_address);
544   IPAddressNumber group_ip;
545   EXPECT_TRUE(ParseIPLiteralToNumber(kGroup, &group_ip));
546 
547   UDPSocket socket(DatagramSocket::DEFAULT_BIND,
548                    RandIntCallback(),
549                    NULL,
550                    NetLog::Source());
551   EXPECT_EQ(OK, socket.Bind(bind_address));
552   EXPECT_EQ(OK, socket.JoinGroup(group_ip));
553   // Joining group multiple times.
554   EXPECT_NE(OK, socket.JoinGroup(group_ip));
555   EXPECT_EQ(OK, socket.LeaveGroup(group_ip));
556   // Leaving group multiple times.
557   EXPECT_NE(OK, socket.LeaveGroup(group_ip));
558 
559   socket.Close();
560 }
561 
562 TEST_F(UDPSocketTest, MulticastOptions) {
563   const int kPort = 9999;
564   IPEndPoint bind_address;
565   CreateUDPAddress("0.0.0.0", kPort, &bind_address);
566 
567   UDPSocket socket(DatagramSocket::DEFAULT_BIND,
568                    RandIntCallback(),
569                    NULL,
570                    NetLog::Source());
571   // Before binding.
572   EXPECT_EQ(OK, socket.SetMulticastLoopbackMode(false));
573   EXPECT_EQ(OK, socket.SetMulticastLoopbackMode(true));
574   EXPECT_EQ(OK, socket.SetMulticastTimeToLive(0));
575   EXPECT_EQ(OK, socket.SetMulticastTimeToLive(3));
576   EXPECT_NE(OK, socket.SetMulticastTimeToLive(-1));
577   EXPECT_EQ(OK, socket.SetMulticastInterface(0));
578 
579   EXPECT_EQ(OK, socket.Bind(bind_address));
580 
581   EXPECT_NE(OK, socket.SetMulticastLoopbackMode(false));
582   EXPECT_NE(OK, socket.SetMulticastTimeToLive(0));
583   EXPECT_NE(OK, socket.SetMulticastInterface(0));
584 
585   socket.Close();
586 }
587 
588 }  // namespace
589 
590 }  // namespace net
591