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