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, ¤t_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