Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2007 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/base/socket_unittest.h"
     12 
     13 #include "webrtc/base/asyncudpsocket.h"
     14 #include "webrtc/base/gunit.h"
     15 #include "webrtc/base/nethelpers.h"
     16 #include "webrtc/base/socketserver.h"
     17 #include "webrtc/base/testclient.h"
     18 #include "webrtc/base/testutils.h"
     19 #include "webrtc/base/thread.h"
     20 
     21 namespace rtc {
     22 
     23 #define MAYBE_SKIP_IPV6                             \
     24   if (!HasIPv6Enabled()) {                          \
     25     LOG(LS_INFO) << "No IPv6... skipping";          \
     26     return;                                         \
     27   }
     28 
     29 
     30 void SocketTest::TestConnectIPv4() {
     31   ConnectInternal(kIPv4Loopback);
     32 }
     33 
     34 void SocketTest::TestConnectIPv6() {
     35   MAYBE_SKIP_IPV6;
     36   ConnectInternal(kIPv6Loopback);
     37 }
     38 
     39 void SocketTest::TestConnectWithDnsLookupIPv4() {
     40   ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
     41 }
     42 
     43 void SocketTest::TestConnectWithDnsLookupIPv6() {
     44   // TODO: Enable this when DNS resolution supports IPv6.
     45   LOG(LS_INFO) << "Skipping IPv6 DNS test";
     46   // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
     47 }
     48 
     49 void SocketTest::TestConnectFailIPv4() {
     50   ConnectFailInternal(kIPv4Loopback);
     51 }
     52 
     53 void SocketTest::TestConnectFailIPv6() {
     54   MAYBE_SKIP_IPV6;
     55   ConnectFailInternal(kIPv6Loopback);
     56 }
     57 
     58 void SocketTest::TestConnectWithDnsLookupFailIPv4() {
     59   ConnectWithDnsLookupFailInternal(kIPv4Loopback);
     60 }
     61 
     62 void SocketTest::TestConnectWithDnsLookupFailIPv6() {
     63   MAYBE_SKIP_IPV6;
     64   ConnectWithDnsLookupFailInternal(kIPv6Loopback);
     65 }
     66 
     67 void SocketTest::TestConnectWithClosedSocketIPv4() {
     68   ConnectWithClosedSocketInternal(kIPv4Loopback);
     69 }
     70 
     71 void SocketTest::TestConnectWithClosedSocketIPv6() {
     72   MAYBE_SKIP_IPV6;
     73   ConnectWithClosedSocketInternal(kIPv6Loopback);
     74 }
     75 
     76 void SocketTest::TestConnectWhileNotClosedIPv4() {
     77   ConnectWhileNotClosedInternal(kIPv4Loopback);
     78 }
     79 
     80 void SocketTest::TestConnectWhileNotClosedIPv6() {
     81   MAYBE_SKIP_IPV6;
     82   ConnectWhileNotClosedInternal(kIPv6Loopback);
     83 }
     84 
     85 void SocketTest::TestServerCloseDuringConnectIPv4() {
     86   ServerCloseDuringConnectInternal(kIPv4Loopback);
     87 }
     88 
     89 void SocketTest::TestServerCloseDuringConnectIPv6() {
     90   MAYBE_SKIP_IPV6;
     91   ServerCloseDuringConnectInternal(kIPv6Loopback);
     92 }
     93 
     94 void SocketTest::TestClientCloseDuringConnectIPv4() {
     95   ClientCloseDuringConnectInternal(kIPv4Loopback);
     96 }
     97 
     98 void SocketTest::TestClientCloseDuringConnectIPv6() {
     99   MAYBE_SKIP_IPV6;
    100   ClientCloseDuringConnectInternal(kIPv6Loopback);
    101 }
    102 
    103 void SocketTest::TestServerCloseIPv4() {
    104   ServerCloseInternal(kIPv4Loopback);
    105 }
    106 
    107 void SocketTest::TestServerCloseIPv6() {
    108   MAYBE_SKIP_IPV6;
    109   ServerCloseInternal(kIPv6Loopback);
    110 }
    111 
    112 void SocketTest::TestCloseInClosedCallbackIPv4() {
    113   CloseInClosedCallbackInternal(kIPv4Loopback);
    114 }
    115 
    116 void SocketTest::TestCloseInClosedCallbackIPv6() {
    117   MAYBE_SKIP_IPV6;
    118   CloseInClosedCallbackInternal(kIPv6Loopback);
    119 }
    120 
    121 void SocketTest::TestSocketServerWaitIPv4() {
    122   SocketServerWaitInternal(kIPv4Loopback);
    123 }
    124 
    125 void SocketTest::TestSocketServerWaitIPv6() {
    126   MAYBE_SKIP_IPV6;
    127   SocketServerWaitInternal(kIPv6Loopback);
    128 }
    129 
    130 void SocketTest::TestTcpIPv4() {
    131   TcpInternal(kIPv4Loopback);
    132 }
    133 
    134 void SocketTest::TestTcpIPv6() {
    135   MAYBE_SKIP_IPV6;
    136   TcpInternal(kIPv6Loopback);
    137 }
    138 
    139 void SocketTest::TestSingleFlowControlCallbackIPv4() {
    140   SingleFlowControlCallbackInternal(kIPv4Loopback);
    141 }
    142 
    143 void SocketTest::TestSingleFlowControlCallbackIPv6() {
    144   MAYBE_SKIP_IPV6;
    145   SingleFlowControlCallbackInternal(kIPv6Loopback);
    146 }
    147 
    148 void SocketTest::TestUdpIPv4() {
    149   UdpInternal(kIPv4Loopback);
    150 }
    151 
    152 void SocketTest::TestUdpIPv6() {
    153   MAYBE_SKIP_IPV6;
    154   UdpInternal(kIPv6Loopback);
    155 }
    156 
    157 void SocketTest::TestUdpReadyToSendIPv4() {
    158 #if !defined(WEBRTC_MAC)
    159   // TODO(ronghuawu): Enable this test on mac/ios.
    160   UdpReadyToSend(kIPv4Loopback);
    161 #endif
    162 }
    163 
    164 void SocketTest::TestUdpReadyToSendIPv6() {
    165 #if defined(WEBRTC_WIN)
    166   // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
    167   MAYBE_SKIP_IPV6;
    168   UdpReadyToSend(kIPv6Loopback);
    169 #endif
    170 }
    171 
    172 void SocketTest::TestGetSetOptionsIPv4() {
    173   GetSetOptionsInternal(kIPv4Loopback);
    174 }
    175 
    176 void SocketTest::TestGetSetOptionsIPv6() {
    177   MAYBE_SKIP_IPV6;
    178   GetSetOptionsInternal(kIPv6Loopback);
    179 }
    180 
    181 // For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
    182 // values on Windows, but an empty address of the same family on Linux/MacOS X.
    183 bool IsUnspecOrEmptyIP(const IPAddress& address) {
    184 #if !defined(WEBRTC_WIN)
    185   return IPIsAny(address);
    186 #else
    187   return address.family() == AF_UNSPEC;
    188 #endif
    189 }
    190 
    191 void SocketTest::ConnectInternal(const IPAddress& loopback) {
    192   testing::StreamSink sink;
    193   SocketAddress accept_addr;
    194 
    195   // Create client.
    196   scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(loopback.family(),
    197                                                         SOCK_STREAM));
    198   sink.Monitor(client.get());
    199   EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
    200   EXPECT_PRED1(IsUnspecOrEmptyIP, client->GetLocalAddress().ipaddr());
    201 
    202   // Create server and listen.
    203   scoped_ptr<AsyncSocket> server(
    204       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    205   sink.Monitor(server.get());
    206   EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
    207   EXPECT_EQ(0, server->Listen(5));
    208   EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
    209 
    210   // Ensure no pending server connections, since we haven't done anything yet.
    211   EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
    212   EXPECT_TRUE(NULL == server->Accept(&accept_addr));
    213   EXPECT_TRUE(accept_addr.IsNil());
    214 
    215   // Attempt connect to listening socket.
    216   EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
    217   EXPECT_FALSE(client->GetLocalAddress().IsNil());
    218   EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
    219 
    220   // Client is connecting, outcome not yet determined.
    221   EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
    222   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
    223   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
    224 
    225   // Server has pending connection, accept it.
    226   EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
    227   scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
    228   ASSERT_TRUE(accepted);
    229   EXPECT_FALSE(accept_addr.IsNil());
    230   EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
    231 
    232   // Connected from server perspective, check the addresses are correct.
    233   EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
    234   EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
    235   EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
    236 
    237   // Connected from client perspective, check the addresses are correct.
    238   EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
    239   EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
    240   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
    241   EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
    242   EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
    243 }
    244 
    245 void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
    246                                               const std::string& host) {
    247   testing::StreamSink sink;
    248   SocketAddress accept_addr;
    249 
    250   // Create client.
    251   scoped_ptr<AsyncSocket> client(
    252       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    253   sink.Monitor(client.get());
    254 
    255   // Create server and listen.
    256   scoped_ptr<AsyncSocket> server(
    257       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    258   sink.Monitor(server.get());
    259   EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
    260   EXPECT_EQ(0, server->Listen(5));
    261 
    262   // Attempt connect to listening socket.
    263   SocketAddress dns_addr(server->GetLocalAddress());
    264   dns_addr.SetIP(host);
    265   EXPECT_EQ(0, client->Connect(dns_addr));
    266   // TODO: Bind when doing DNS lookup.
    267   //EXPECT_NE(kEmptyAddr, client->GetLocalAddress());  // Implicit Bind
    268 
    269   // Client is connecting, outcome not yet determined.
    270   EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
    271   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
    272   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
    273 
    274   // Server has pending connection, accept it.
    275   EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
    276   scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
    277   ASSERT_TRUE(accepted);
    278   EXPECT_FALSE(accept_addr.IsNil());
    279   EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
    280 
    281   // Connected from server perspective, check the addresses are correct.
    282   EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
    283   EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
    284   EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
    285 
    286   // Connected from client perspective, check the addresses are correct.
    287   EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
    288   EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
    289   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
    290   EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
    291   EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
    292 }
    293 
    294 void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
    295   testing::StreamSink sink;
    296   SocketAddress accept_addr;
    297 
    298   // Create client.
    299   scoped_ptr<AsyncSocket> client(
    300       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    301   sink.Monitor(client.get());
    302 
    303   // Create server, but don't listen yet.
    304   scoped_ptr<AsyncSocket> server(
    305       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    306   sink.Monitor(server.get());
    307   EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
    308 
    309   // Attempt connect to a non-existent socket.
    310   // We don't connect to the server socket created above, since on
    311   // MacOS it takes about 75 seconds to get back an error!
    312   SocketAddress bogus_addr(loopback, 65535);
    313   EXPECT_EQ(0, client->Connect(bogus_addr));
    314 
    315   // Wait for connection to fail (ECONNREFUSED).
    316   EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
    317   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
    318   EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
    319   EXPECT_TRUE(client->GetRemoteAddress().IsNil());
    320 
    321   // Should be no pending server connections.
    322   EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
    323   EXPECT_TRUE(NULL == server->Accept(&accept_addr));
    324   EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
    325 }
    326 
    327 void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
    328   testing::StreamSink sink;
    329   SocketAddress accept_addr;
    330 
    331   // Create client.
    332   scoped_ptr<AsyncSocket> client(
    333       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    334   sink.Monitor(client.get());
    335 
    336   // Create server, but don't listen yet.
    337   scoped_ptr<AsyncSocket> server(
    338       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    339   sink.Monitor(server.get());
    340   EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
    341 
    342   // Attempt connect to a non-existent host.
    343   // We don't connect to the server socket created above, since on
    344   // MacOS it takes about 75 seconds to get back an error!
    345   SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
    346   EXPECT_EQ(0, client->Connect(bogus_dns_addr));
    347 
    348   // Wait for connection to fail (EHOSTNOTFOUND).
    349   bool dns_lookup_finished = false;
    350   WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
    351         dns_lookup_finished);
    352   if (!dns_lookup_finished) {
    353     LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
    354                     << "seconds.";
    355     return;
    356   }
    357 
    358   EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
    359   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
    360   EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
    361   EXPECT_TRUE(client->GetRemoteAddress().IsNil());
    362   // Should be no pending server connections.
    363   EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
    364   EXPECT_TRUE(NULL == server->Accept(&accept_addr));
    365   EXPECT_TRUE(accept_addr.IsNil());
    366 }
    367 
    368 void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
    369   // Create server and listen.
    370   scoped_ptr<AsyncSocket> server(
    371       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    372   EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
    373   EXPECT_EQ(0, server->Listen(5));
    374 
    375   // Create a client and put in to CS_CLOSED state.
    376   scoped_ptr<AsyncSocket> client(
    377       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    378   EXPECT_EQ(0, client->Close());
    379   EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
    380 
    381   // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
    382   EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
    383   EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
    384 }
    385 
    386 void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
    387   // Create server and listen.
    388   testing::StreamSink sink;
    389   scoped_ptr<AsyncSocket> server(
    390       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    391   sink.Monitor(server.get());
    392   EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
    393   EXPECT_EQ(0, server->Listen(5));
    394   // Create client, connect.
    395   scoped_ptr<AsyncSocket> client(
    396       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    397   EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
    398   EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
    399   // Try to connect again. Should fail, but not interfere with original attempt.
    400   EXPECT_EQ(SOCKET_ERROR,
    401             client->Connect(SocketAddress(server->GetLocalAddress())));
    402 
    403   // Accept the original connection.
    404   SocketAddress accept_addr;
    405   EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
    406   scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
    407   ASSERT_TRUE(accepted);
    408   EXPECT_FALSE(accept_addr.IsNil());
    409 
    410   // Check the states and addresses.
    411   EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
    412   EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
    413   EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
    414   EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
    415   EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
    416   EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
    417 
    418   // Try to connect again, to an unresolved hostname.
    419   // Shouldn't break anything.
    420   EXPECT_EQ(SOCKET_ERROR,
    421             client->Connect(SocketAddress("localhost",
    422                                           server->GetLocalAddress().port())));
    423   EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
    424   EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
    425   EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
    426   EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
    427 }
    428 
    429 void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
    430   testing::StreamSink sink;
    431 
    432   // Create client.
    433   scoped_ptr<AsyncSocket> client(
    434       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    435   sink.Monitor(client.get());
    436 
    437   // Create server and listen.
    438   scoped_ptr<AsyncSocket> server(
    439       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    440   sink.Monitor(server.get());
    441   EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
    442   EXPECT_EQ(0, server->Listen(5));
    443 
    444   // Attempt connect to listening socket.
    445   EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
    446 
    447   // Close down the server while the socket is in the accept queue.
    448   EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
    449   server->Close();
    450 
    451   // This should fail the connection for the client. Clean up.
    452   EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
    453   EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
    454   client->Close();
    455 }
    456 
    457 void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
    458   testing::StreamSink sink;
    459   SocketAddress accept_addr;
    460 
    461   // Create client.
    462   scoped_ptr<AsyncSocket> client(
    463       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    464   sink.Monitor(client.get());
    465 
    466   // Create server and listen.
    467   scoped_ptr<AsyncSocket> server(
    468       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    469   sink.Monitor(server.get());
    470   EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
    471   EXPECT_EQ(0, server->Listen(5));
    472 
    473   // Attempt connect to listening socket.
    474   EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
    475 
    476   // Close down the client while the socket is in the accept queue.
    477   EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
    478   client->Close();
    479 
    480   // The connection should still be able to be accepted.
    481   scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
    482   ASSERT_TRUE(accepted);
    483   sink.Monitor(accepted.get());
    484   EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
    485 
    486   // The accepted socket should then close (possibly with err, timing-related)
    487   EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
    488   EXPECT_TRUE(sink.Check(accepted.get(), testing::SSE_CLOSE) ||
    489               sink.Check(accepted.get(), testing::SSE_ERROR));
    490 
    491   // The client should not get a close event.
    492   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
    493 }
    494 
    495 void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
    496   testing::StreamSink sink;
    497   SocketAddress accept_addr;
    498 
    499   // Create client.
    500   scoped_ptr<AsyncSocket> client(
    501       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    502   sink.Monitor(client.get());
    503 
    504   // Create server and listen.
    505   scoped_ptr<AsyncSocket> server(
    506       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    507   sink.Monitor(server.get());
    508   EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
    509   EXPECT_EQ(0, server->Listen(5));
    510 
    511   // Attempt connection.
    512   EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
    513 
    514   // Accept connection.
    515   EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
    516   scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
    517   ASSERT_TRUE(accepted);
    518   sink.Monitor(accepted.get());
    519 
    520   // Both sides are now connected.
    521   EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
    522   EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
    523   EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
    524   EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
    525 
    526   // Send data to the client, and then close the connection.
    527   EXPECT_EQ(1, accepted->Send("a", 1));
    528   accepted->Close();
    529   EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
    530 
    531   // Expect that the client is notified, and has not yet closed.
    532   EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
    533   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
    534   EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
    535 
    536   // Ensure the data can be read.
    537   char buffer[10];
    538   EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer)));
    539   EXPECT_EQ('a', buffer[0]);
    540 
    541   // Now we should close, but the remote address will remain.
    542   EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
    543   EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
    544   EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
    545 
    546   // The closer should not get a close signal.
    547   EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_CLOSE));
    548   EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
    549 
    550   // And the closee should only get a single signal.
    551   Thread::Current()->ProcessMessages(0);
    552   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
    553 
    554   // Close down the client and ensure all is good.
    555   client->Close();
    556   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
    557   EXPECT_TRUE(client->GetRemoteAddress().IsNil());
    558 }
    559 
    560 class SocketCloser : public sigslot::has_slots<> {
    561  public:
    562   void OnClose(AsyncSocket* socket, int error) {
    563     socket->Close();  // Deleting here would blow up the vector of handlers
    564                       // for the socket's signal.
    565   }
    566 };
    567 
    568 void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
    569   testing::StreamSink sink;
    570   SocketCloser closer;
    571   SocketAddress accept_addr;
    572 
    573   // Create client.
    574   scoped_ptr<AsyncSocket> client(
    575       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    576   sink.Monitor(client.get());
    577   client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
    578 
    579   // Create server and listen.
    580   scoped_ptr<AsyncSocket> server(
    581       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    582   sink.Monitor(server.get());
    583   EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
    584   EXPECT_EQ(0, server->Listen(5));
    585 
    586   // Attempt connection.
    587   EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
    588 
    589   // Accept connection.
    590   EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
    591   scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
    592   ASSERT_TRUE(accepted);
    593   sink.Monitor(accepted.get());
    594 
    595   // Both sides are now connected.
    596   EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
    597   EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
    598   EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
    599   EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
    600 
    601   // Send data to the client, and then close the connection.
    602   accepted->Close();
    603   EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
    604 
    605   // Expect that the client is notified, and has not yet closed.
    606   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
    607   EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
    608 
    609   // Now we should be closed and invalidated
    610   EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
    611   EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
    612   EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
    613 }
    614 
    615 class Sleeper : public MessageHandler {
    616  public:
    617   Sleeper() {}
    618   void OnMessage(Message* msg) {
    619     Thread::Current()->SleepMs(500);
    620   }
    621 };
    622 
    623 void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
    624   testing::StreamSink sink;
    625   SocketAddress accept_addr;
    626 
    627   // Create & connect server and client sockets.
    628   scoped_ptr<AsyncSocket> client(
    629       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    630   scoped_ptr<AsyncSocket> server(
    631       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    632   sink.Monitor(client.get());
    633   sink.Monitor(server.get());
    634   EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
    635   EXPECT_EQ(0, server->Listen(5));
    636 
    637   EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
    638   EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
    639 
    640   scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
    641   ASSERT_TRUE(accepted);
    642   sink.Monitor(accepted.get());
    643   EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
    644   EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
    645   EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
    646 
    647   EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
    648   EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
    649   EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
    650   EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
    651   EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
    652 
    653   // Do an i/o operation, triggering an eventual callback.
    654   EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
    655   char buf[1024] = {0};
    656 
    657   EXPECT_EQ(1024, client->Send(buf, 1024));
    658   EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
    659 
    660   // Shouldn't signal when blocked in a thread Send, where process_io is false.
    661   scoped_ptr<Thread> thread(new Thread());
    662   thread->Start();
    663   Sleeper sleeper;
    664   TypedMessageData<AsyncSocket*> data(client.get());
    665   thread->Send(&sleeper, 0, &data);
    666   EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
    667 
    668   // But should signal when process_io is true.
    669   EXPECT_TRUE_WAIT((sink.Check(accepted.get(), testing::SSE_READ)), kTimeout);
    670   EXPECT_LT(0, accepted->Recv(buf, 1024));
    671 }
    672 
    673 void SocketTest::TcpInternal(const IPAddress& loopback) {
    674   testing::StreamSink sink;
    675   SocketAddress accept_addr;
    676 
    677   // Create test data.
    678   const size_t kDataSize = 1024 * 1024;
    679   scoped_ptr<char[]> send_buffer(new char[kDataSize]);
    680   scoped_ptr<char[]> recv_buffer(new char[kDataSize]);
    681   size_t send_pos = 0, recv_pos = 0;
    682   for (size_t i = 0; i < kDataSize; ++i) {
    683     send_buffer[i] = static_cast<char>(i % 256);
    684     recv_buffer[i] = 0;
    685   }
    686 
    687   // Create client.
    688   scoped_ptr<AsyncSocket> client(
    689       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    690   sink.Monitor(client.get());
    691 
    692   // Create server and listen.
    693   scoped_ptr<AsyncSocket> server(
    694       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    695   sink.Monitor(server.get());
    696   EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
    697   EXPECT_EQ(0, server->Listen(5));
    698 
    699   // Attempt connection.
    700   EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
    701 
    702   // Accept connection.
    703   EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
    704   scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
    705   ASSERT_TRUE(accepted);
    706   sink.Monitor(accepted.get());
    707 
    708   // Both sides are now connected.
    709   EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
    710   EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
    711   EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
    712   EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
    713 
    714   // Send and receive a bunch of data.
    715   bool send_waiting_for_writability = false;
    716   bool send_expect_success = true;
    717   bool recv_waiting_for_readability = true;
    718   bool recv_expect_success = false;
    719   int data_in_flight = 0;
    720   while (recv_pos < kDataSize) {
    721     // Send as much as we can if we've been cleared to send.
    722     while (!send_waiting_for_writability && send_pos < kDataSize) {
    723       int tosend = static_cast<int>(kDataSize - send_pos);
    724       int sent = accepted->Send(send_buffer.get() + send_pos, tosend);
    725       if (send_expect_success) {
    726         // The first Send() after connecting or getting writability should
    727         // succeed and send some data.
    728         EXPECT_GT(sent, 0);
    729         send_expect_success = false;
    730       }
    731       if (sent >= 0) {
    732         EXPECT_LE(sent, tosend);
    733         send_pos += sent;
    734         data_in_flight += sent;
    735       } else {
    736         ASSERT_TRUE(accepted->IsBlocking());
    737         send_waiting_for_writability = true;
    738       }
    739     }
    740 
    741     // Read all the sent data.
    742     while (data_in_flight > 0) {
    743       if (recv_waiting_for_readability) {
    744         // Wait until data is available.
    745         EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
    746         recv_waiting_for_readability = false;
    747         recv_expect_success = true;
    748       }
    749 
    750       // Receive as much as we can get in a single recv call.
    751       int rcvd = client->Recv(recv_buffer.get() + recv_pos,
    752                               kDataSize - recv_pos);
    753 
    754       if (recv_expect_success) {
    755         // The first Recv() after getting readability should succeed and receive
    756         // some data.
    757         // TODO: The following line is disabled due to flakey pulse
    758         //     builds.  Re-enable if/when possible.
    759         // EXPECT_GT(rcvd, 0);
    760         recv_expect_success = false;
    761       }
    762       if (rcvd >= 0) {
    763         EXPECT_LE(rcvd, data_in_flight);
    764         recv_pos += rcvd;
    765         data_in_flight -= rcvd;
    766       } else {
    767         ASSERT_TRUE(client->IsBlocking());
    768         recv_waiting_for_readability = true;
    769       }
    770     }
    771 
    772     // Once all that we've sent has been rcvd, expect to be able to send again.
    773     if (send_waiting_for_writability) {
    774       EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE),
    775                        kTimeout);
    776       send_waiting_for_writability = false;
    777       send_expect_success = true;
    778     }
    779   }
    780 
    781   // The received data matches the sent data.
    782   EXPECT_EQ(kDataSize, send_pos);
    783   EXPECT_EQ(kDataSize, recv_pos);
    784   EXPECT_EQ(0, memcmp(recv_buffer.get(), send_buffer.get(), kDataSize));
    785 
    786   // Close down.
    787   accepted->Close();
    788   EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
    789   EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
    790   client->Close();
    791 }
    792 
    793 void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
    794   testing::StreamSink sink;
    795   SocketAddress accept_addr;
    796 
    797   // Create client.
    798   scoped_ptr<AsyncSocket> client(
    799       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    800   sink.Monitor(client.get());
    801 
    802   // Create server and listen.
    803   scoped_ptr<AsyncSocket> server(
    804       ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
    805   sink.Monitor(server.get());
    806   EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
    807   EXPECT_EQ(0, server->Listen(5));
    808 
    809   // Attempt connection.
    810   EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
    811 
    812   // Accept connection.
    813   EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
    814   scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
    815   ASSERT_TRUE(accepted);
    816   sink.Monitor(accepted.get());
    817 
    818   // Both sides are now connected.
    819   EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
    820   EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
    821   EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
    822   EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
    823 
    824   // Expect a writable callback from the connect.
    825   EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
    826 
    827   // Fill the socket buffer.
    828   char buf[1024 * 16] = {0};
    829   int sends = 0;
    830   while (++sends && accepted->Send(&buf, ARRAY_SIZE(buf)) != -1) {}
    831   EXPECT_TRUE(accepted->IsBlocking());
    832 
    833   // Wait until data is available.
    834   EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
    835 
    836   // Pull data.
    837   for (int i = 0; i < sends; ++i) {
    838     client->Recv(buf, ARRAY_SIZE(buf));
    839   }
    840 
    841   // Expect at least one additional writable callback.
    842   EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
    843 
    844   // Adding data in response to the writeable callback shouldn't cause infinite
    845   // callbacks.
    846   int extras = 0;
    847   for (int i = 0; i < 100; ++i) {
    848     accepted->Send(&buf, ARRAY_SIZE(buf));
    849     rtc::Thread::Current()->ProcessMessages(1);
    850     if (sink.Check(accepted.get(), testing::SSE_WRITE)) {
    851       extras++;
    852     }
    853   }
    854   EXPECT_LT(extras, 2);
    855 
    856   // Close down.
    857   accepted->Close();
    858   client->Close();
    859 }
    860 
    861 void SocketTest::UdpInternal(const IPAddress& loopback) {
    862   SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
    863   // Test basic bind and connect behavior.
    864   AsyncSocket* socket =
    865       ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
    866   EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
    867   EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
    868   SocketAddress addr1 = socket->GetLocalAddress();
    869   EXPECT_EQ(0, socket->Connect(addr1));
    870   EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
    871   socket->Close();
    872   EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
    873   delete socket;
    874 
    875   // Test send/receive behavior.
    876   scoped_ptr<TestClient> client1(
    877       new TestClient(AsyncUDPSocket::Create(ss_, addr1)));
    878   scoped_ptr<TestClient> client2(
    879       new TestClient(AsyncUDPSocket::Create(ss_, empty)));
    880 
    881   SocketAddress addr2;
    882   EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
    883   EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
    884 
    885   SocketAddress addr3;
    886   EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
    887   EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
    888   EXPECT_EQ(addr3, addr1);
    889   // TODO: figure out what the intent is here
    890   for (int i = 0; i < 10; ++i) {
    891     client2.reset(new TestClient(AsyncUDPSocket::Create(ss_, empty)));
    892 
    893     SocketAddress addr4;
    894     EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
    895     EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
    896     EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
    897 
    898     SocketAddress addr5;
    899     EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
    900     EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
    901     EXPECT_EQ(addr5, addr1);
    902 
    903     addr2 = addr4;
    904   }
    905 }
    906 
    907 void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
    908   SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
    909   // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
    910   // documentation.
    911   // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
    912   std::string dest = (loopback.family() == AF_INET6) ?
    913       "2001:db8::1" : "192.0.2.0";
    914   SocketAddress test_addr(dest, 2345);
    915 
    916   // Test send
    917   scoped_ptr<TestClient> client(
    918       new TestClient(AsyncUDPSocket::Create(ss_, empty)));
    919   int test_packet_size = 1200;
    920   rtc::scoped_ptr<char[]> test_packet(new char[test_packet_size]);
    921   // Init the test packet just to avoid memcheck warning.
    922   memset(test_packet.get(), 0, test_packet_size);
    923   // Set the send buffer size to the same size as the test packet to have a
    924   // better chance to get EWOULDBLOCK.
    925   int send_buffer_size = test_packet_size;
    926 #if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
    927   send_buffer_size /= 2;
    928 #endif
    929   client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
    930 
    931   int error = 0;
    932   uint32 start_ms = Time();
    933   int sent_packet_num = 0;
    934   int expected_error = EWOULDBLOCK;
    935   while (start_ms + kTimeout > Time()) {
    936     int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
    937     ++sent_packet_num;
    938     if (ret != test_packet_size) {
    939       error = client->GetError();
    940       if (error == expected_error) {
    941         LOG(LS_INFO) << "Got expected error code after sending "
    942                      << sent_packet_num << " packets.";
    943         break;
    944       }
    945     }
    946   }
    947   EXPECT_EQ(expected_error, error);
    948   EXPECT_FALSE(client->ready_to_send());
    949   EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
    950   LOG(LS_INFO) << "Got SignalReadyToSend";
    951 }
    952 
    953 void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
    954   rtc::scoped_ptr<AsyncSocket> socket(
    955       ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
    956   socket->Bind(SocketAddress(loopback, 0));
    957 
    958   // Check SNDBUF/RCVBUF.
    959   const int desired_size = 12345;
    960 #if defined(WEBRTC_LINUX)
    961   // Yes, really.  It's in the kernel source.
    962   const int expected_size = desired_size * 2;
    963 #else   // !WEBRTC_LINUX
    964   const int expected_size = desired_size;
    965 #endif  // !WEBRTC_LINUX
    966   int recv_size = 0;
    967   int send_size = 0;
    968   // get the initial sizes
    969   ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
    970   ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
    971   // set our desired sizes
    972   ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
    973   ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
    974   // get the sizes again
    975   ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
    976   ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
    977   // make sure they are right
    978   ASSERT_EQ(expected_size, recv_size);
    979   ASSERT_EQ(expected_size, send_size);
    980 
    981   // Check that we can't set NODELAY on a UDP socket.
    982   int current_nd, desired_nd = 1;
    983   ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
    984   ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
    985 
    986   // Skip the esimate MTU test for IPv6 for now.
    987   if (loopback.family() != AF_INET6) {
    988     // Try estimating MTU.
    989     rtc::scoped_ptr<AsyncSocket>
    990         mtu_socket(
    991             ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
    992     mtu_socket->Bind(SocketAddress(loopback, 0));
    993     uint16 mtu;
    994     // should fail until we connect
    995     ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
    996     mtu_socket->Connect(SocketAddress(loopback, 0));
    997 #if defined(WEBRTC_WIN)
    998     // now it should succeed
    999     ASSERT_NE(-1, mtu_socket->EstimateMTU(&mtu));
   1000     ASSERT_GE(mtu, 1492);  // should be at least the 1492 "plateau" on localhost
   1001 #elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
   1002     // except on WEBRTC_MAC && !WEBRTC_IOS, where it's not yet implemented
   1003     ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
   1004 #else
   1005     // and the behavior seems unpredictable on Linux,
   1006     // failing on the build machine
   1007     // but succeeding on my Ubiquity instance.
   1008 #endif
   1009   }
   1010 }
   1011 
   1012 }  // namespace rtc
   1013