blob: 4a59a169b8a8e065f3ebb75eb55cc1df8a09538e [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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
jbauch555604a2016-04-26 03:13:22 -070011#include <memory>
12
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000013#include "webrtc/base/socket_unittest.h"
14
tfarina5237aaf2015-11-10 23:44:30 -080015#include "webrtc/base/arraysize.h"
jbauchf2a2bf42016-02-03 16:45:32 -080016#include "webrtc/base/buffer.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000017#include "webrtc/base/asyncudpsocket.h"
18#include "webrtc/base/gunit.h"
19#include "webrtc/base/nethelpers.h"
20#include "webrtc/base/socketserver.h"
21#include "webrtc/base/testclient.h"
22#include "webrtc/base/testutils.h"
23#include "webrtc/base/thread.h"
24
25namespace rtc {
26
27#define MAYBE_SKIP_IPV6 \
28 if (!HasIPv6Enabled()) { \
29 LOG(LS_INFO) << "No IPv6... skipping"; \
30 return; \
31 }
32
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070033// Data size to be used in TcpInternal tests.
34static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000035
36void SocketTest::TestConnectIPv4() {
37 ConnectInternal(kIPv4Loopback);
38}
39
40void SocketTest::TestConnectIPv6() {
41 MAYBE_SKIP_IPV6;
42 ConnectInternal(kIPv6Loopback);
43}
44
45void SocketTest::TestConnectWithDnsLookupIPv4() {
46 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
47}
48
49void SocketTest::TestConnectWithDnsLookupIPv6() {
50 // TODO: Enable this when DNS resolution supports IPv6.
51 LOG(LS_INFO) << "Skipping IPv6 DNS test";
52 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
53}
54
55void SocketTest::TestConnectFailIPv4() {
56 ConnectFailInternal(kIPv4Loopback);
57}
58
59void SocketTest::TestConnectFailIPv6() {
60 MAYBE_SKIP_IPV6;
61 ConnectFailInternal(kIPv6Loopback);
62}
63
64void SocketTest::TestConnectWithDnsLookupFailIPv4() {
65 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
66}
67
68void SocketTest::TestConnectWithDnsLookupFailIPv6() {
69 MAYBE_SKIP_IPV6;
70 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
71}
72
73void SocketTest::TestConnectWithClosedSocketIPv4() {
74 ConnectWithClosedSocketInternal(kIPv4Loopback);
75}
76
77void SocketTest::TestConnectWithClosedSocketIPv6() {
78 MAYBE_SKIP_IPV6;
79 ConnectWithClosedSocketInternal(kIPv6Loopback);
80}
81
82void SocketTest::TestConnectWhileNotClosedIPv4() {
83 ConnectWhileNotClosedInternal(kIPv4Loopback);
84}
85
86void SocketTest::TestConnectWhileNotClosedIPv6() {
87 MAYBE_SKIP_IPV6;
88 ConnectWhileNotClosedInternal(kIPv6Loopback);
89}
90
91void SocketTest::TestServerCloseDuringConnectIPv4() {
92 ServerCloseDuringConnectInternal(kIPv4Loopback);
93}
94
95void SocketTest::TestServerCloseDuringConnectIPv6() {
96 MAYBE_SKIP_IPV6;
97 ServerCloseDuringConnectInternal(kIPv6Loopback);
98}
99
100void SocketTest::TestClientCloseDuringConnectIPv4() {
101 ClientCloseDuringConnectInternal(kIPv4Loopback);
102}
103
104void SocketTest::TestClientCloseDuringConnectIPv6() {
105 MAYBE_SKIP_IPV6;
106 ClientCloseDuringConnectInternal(kIPv6Loopback);
107}
108
109void SocketTest::TestServerCloseIPv4() {
110 ServerCloseInternal(kIPv4Loopback);
111}
112
113void SocketTest::TestServerCloseIPv6() {
114 MAYBE_SKIP_IPV6;
115 ServerCloseInternal(kIPv6Loopback);
116}
117
118void SocketTest::TestCloseInClosedCallbackIPv4() {
119 CloseInClosedCallbackInternal(kIPv4Loopback);
120}
121
122void SocketTest::TestCloseInClosedCallbackIPv6() {
123 MAYBE_SKIP_IPV6;
124 CloseInClosedCallbackInternal(kIPv6Loopback);
125}
126
127void SocketTest::TestSocketServerWaitIPv4() {
128 SocketServerWaitInternal(kIPv4Loopback);
129}
130
131void SocketTest::TestSocketServerWaitIPv6() {
132 MAYBE_SKIP_IPV6;
133 SocketServerWaitInternal(kIPv6Loopback);
134}
135
136void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800137 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000138}
139
140void SocketTest::TestTcpIPv6() {
141 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800142 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000143}
144
145void SocketTest::TestSingleFlowControlCallbackIPv4() {
146 SingleFlowControlCallbackInternal(kIPv4Loopback);
147}
148
149void SocketTest::TestSingleFlowControlCallbackIPv6() {
150 MAYBE_SKIP_IPV6;
151 SingleFlowControlCallbackInternal(kIPv6Loopback);
152}
153
154void SocketTest::TestUdpIPv4() {
155 UdpInternal(kIPv4Loopback);
156}
157
158void SocketTest::TestUdpIPv6() {
159 MAYBE_SKIP_IPV6;
160 UdpInternal(kIPv6Loopback);
161}
162
163void SocketTest::TestUdpReadyToSendIPv4() {
164#if !defined(WEBRTC_MAC)
165 // TODO(ronghuawu): Enable this test on mac/ios.
166 UdpReadyToSend(kIPv4Loopback);
167#endif
168}
169
170void SocketTest::TestUdpReadyToSendIPv6() {
171#if defined(WEBRTC_WIN)
172 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
173 MAYBE_SKIP_IPV6;
174 UdpReadyToSend(kIPv6Loopback);
175#endif
176}
177
178void SocketTest::TestGetSetOptionsIPv4() {
179 GetSetOptionsInternal(kIPv4Loopback);
180}
181
182void SocketTest::TestGetSetOptionsIPv6() {
183 MAYBE_SKIP_IPV6;
184 GetSetOptionsInternal(kIPv6Loopback);
185}
186
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700187void SocketTest::TestSocketRecvTimestampIPv4() {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200188 SocketRecvTimestamp(kIPv4Loopback);
189}
190
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700191void SocketTest::TestSocketRecvTimestampIPv6() {
192 MAYBE_SKIP_IPV6;
193 SocketRecvTimestamp(kIPv6Loopback);
194}
195
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000196// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
197// values on Windows, but an empty address of the same family on Linux/MacOS X.
198bool IsUnspecOrEmptyIP(const IPAddress& address) {
199#if !defined(WEBRTC_WIN)
200 return IPIsAny(address);
201#else
202 return address.family() == AF_UNSPEC;
203#endif
204}
205
206void SocketTest::ConnectInternal(const IPAddress& loopback) {
207 testing::StreamSink sink;
208 SocketAddress accept_addr;
209
210 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700211 std::unique_ptr<AsyncSocket> client(
212 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000213 sink.Monitor(client.get());
214 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
215 EXPECT_PRED1(IsUnspecOrEmptyIP, client->GetLocalAddress().ipaddr());
216
217 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700218 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000219 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
220 sink.Monitor(server.get());
221 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
222 EXPECT_EQ(0, server->Listen(5));
223 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
224
225 // Ensure no pending server connections, since we haven't done anything yet.
226 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800227 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000228 EXPECT_TRUE(accept_addr.IsNil());
229
230 // Attempt connect to listening socket.
231 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
232 EXPECT_FALSE(client->GetLocalAddress().IsNil());
233 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
234
235 // Client is connecting, outcome not yet determined.
236 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
237 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
238 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
239
240 // Server has pending connection, accept it.
241 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700242 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000243 ASSERT_TRUE(accepted);
244 EXPECT_FALSE(accept_addr.IsNil());
245 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
246
247 // Connected from server perspective, check the addresses are correct.
248 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
249 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
250 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
251
252 // Connected from client perspective, check the addresses are correct.
253 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
254 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
255 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
256 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
257 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
258}
259
260void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
261 const std::string& host) {
262 testing::StreamSink sink;
263 SocketAddress accept_addr;
264
265 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700266 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000267 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
268 sink.Monitor(client.get());
269
270 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700271 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000272 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
273 sink.Monitor(server.get());
274 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
275 EXPECT_EQ(0, server->Listen(5));
276
277 // Attempt connect to listening socket.
278 SocketAddress dns_addr(server->GetLocalAddress());
279 dns_addr.SetIP(host);
280 EXPECT_EQ(0, client->Connect(dns_addr));
281 // TODO: Bind when doing DNS lookup.
282 //EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
283
284 // Client is connecting, outcome not yet determined.
285 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
286 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
287 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
288
289 // Server has pending connection, accept it.
290 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700291 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000292 ASSERT_TRUE(accepted);
293 EXPECT_FALSE(accept_addr.IsNil());
294 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
295
296 // Connected from server perspective, check the addresses are correct.
297 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
298 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
299 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
300
301 // Connected from client perspective, check the addresses are correct.
302 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
303 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
304 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
305 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
306 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
307}
308
309void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
310 testing::StreamSink sink;
311 SocketAddress accept_addr;
312
313 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700314 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000315 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
316 sink.Monitor(client.get());
317
318 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700319 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000320 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
321 sink.Monitor(server.get());
322 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
323
324 // Attempt connect to a non-existent socket.
325 // We don't connect to the server socket created above, since on
326 // MacOS it takes about 75 seconds to get back an error!
327 SocketAddress bogus_addr(loopback, 65535);
328 EXPECT_EQ(0, client->Connect(bogus_addr));
329
330 // Wait for connection to fail (ECONNREFUSED).
331 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
332 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
333 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
334 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
335
336 // Should be no pending server connections.
337 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800338 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000339 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
340}
341
342void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
343 testing::StreamSink sink;
344 SocketAddress accept_addr;
345
346 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700347 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000348 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
349 sink.Monitor(client.get());
350
351 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700352 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000353 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
354 sink.Monitor(server.get());
355 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
356
357 // Attempt connect to a non-existent host.
358 // We don't connect to the server socket created above, since on
359 // MacOS it takes about 75 seconds to get back an error!
360 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
361 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
362
363 // Wait for connection to fail (EHOSTNOTFOUND).
364 bool dns_lookup_finished = false;
365 WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
366 dns_lookup_finished);
367 if (!dns_lookup_finished) {
368 LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
369 << "seconds.";
370 return;
371 }
372
373 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
374 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
375 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
376 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
377 // Should be no pending server connections.
378 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800379 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000380 EXPECT_TRUE(accept_addr.IsNil());
381}
382
383void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
384 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700385 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000386 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
387 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
388 EXPECT_EQ(0, server->Listen(5));
389
390 // Create a client and put in to CS_CLOSED state.
jbauch555604a2016-04-26 03:13:22 -0700391 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000392 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
393 EXPECT_EQ(0, client->Close());
394 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
395
396 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
397 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
398 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
399}
400
401void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
402 // Create server and listen.
403 testing::StreamSink sink;
jbauch555604a2016-04-26 03:13:22 -0700404 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000405 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
406 sink.Monitor(server.get());
407 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
408 EXPECT_EQ(0, server->Listen(5));
409 // Create client, connect.
jbauch555604a2016-04-26 03:13:22 -0700410 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000411 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
412 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
413 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
414 // Try to connect again. Should fail, but not interfere with original attempt.
415 EXPECT_EQ(SOCKET_ERROR,
416 client->Connect(SocketAddress(server->GetLocalAddress())));
417
418 // Accept the original connection.
419 SocketAddress accept_addr;
420 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700421 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000422 ASSERT_TRUE(accepted);
423 EXPECT_FALSE(accept_addr.IsNil());
424
425 // Check the states and addresses.
426 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
427 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
428 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
429 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
430 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
431 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
432
433 // Try to connect again, to an unresolved hostname.
434 // Shouldn't break anything.
435 EXPECT_EQ(SOCKET_ERROR,
436 client->Connect(SocketAddress("localhost",
437 server->GetLocalAddress().port())));
438 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
439 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
440 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
441 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
442}
443
444void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
445 testing::StreamSink sink;
446
447 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700448 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000449 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
450 sink.Monitor(client.get());
451
452 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700453 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000454 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
455 sink.Monitor(server.get());
456 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
457 EXPECT_EQ(0, server->Listen(5));
458
459 // Attempt connect to listening socket.
460 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
461
462 // Close down the server while the socket is in the accept queue.
463 EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
464 server->Close();
465
466 // This should fail the connection for the client. Clean up.
467 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
468 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
469 client->Close();
470}
471
472void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
473 testing::StreamSink sink;
474 SocketAddress accept_addr;
475
476 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700477 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000478 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
479 sink.Monitor(client.get());
480
481 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700482 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000483 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
484 sink.Monitor(server.get());
485 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
486 EXPECT_EQ(0, server->Listen(5));
487
488 // Attempt connect to listening socket.
489 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
490
491 // Close down the client while the socket is in the accept queue.
492 EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
493 client->Close();
494
495 // The connection should still be able to be accepted.
jbauch555604a2016-04-26 03:13:22 -0700496 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000497 ASSERT_TRUE(accepted);
498 sink.Monitor(accepted.get());
499 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
500
501 // The accepted socket should then close (possibly with err, timing-related)
502 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
503 EXPECT_TRUE(sink.Check(accepted.get(), testing::SSE_CLOSE) ||
504 sink.Check(accepted.get(), testing::SSE_ERROR));
505
506 // The client should not get a close event.
507 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
508}
509
510void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
511 testing::StreamSink sink;
512 SocketAddress accept_addr;
513
514 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700515 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000516 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
517 sink.Monitor(client.get());
518
519 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700520 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000521 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
522 sink.Monitor(server.get());
523 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
524 EXPECT_EQ(0, server->Listen(5));
525
526 // Attempt connection.
527 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
528
529 // Accept connection.
530 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700531 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000532 ASSERT_TRUE(accepted);
533 sink.Monitor(accepted.get());
534
535 // Both sides are now connected.
536 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
537 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
538 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
539 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
540
541 // Send data to the client, and then close the connection.
542 EXPECT_EQ(1, accepted->Send("a", 1));
543 accepted->Close();
544 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
545
546 // Expect that the client is notified, and has not yet closed.
547 EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
548 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
549 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
550
551 // Ensure the data can be read.
552 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200553 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000554 EXPECT_EQ('a', buffer[0]);
555
556 // Now we should close, but the remote address will remain.
557 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
558 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
559 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
560
561 // The closer should not get a close signal.
562 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_CLOSE));
563 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
564
565 // And the closee should only get a single signal.
566 Thread::Current()->ProcessMessages(0);
567 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
568
569 // Close down the client and ensure all is good.
570 client->Close();
571 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
572 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
573}
574
575class SocketCloser : public sigslot::has_slots<> {
576 public:
577 void OnClose(AsyncSocket* socket, int error) {
578 socket->Close(); // Deleting here would blow up the vector of handlers
579 // for the socket's signal.
580 }
581};
582
583void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
584 testing::StreamSink sink;
585 SocketCloser closer;
586 SocketAddress accept_addr;
587
588 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700589 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000590 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
591 sink.Monitor(client.get());
592 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
593
594 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700595 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000596 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
597 sink.Monitor(server.get());
598 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
599 EXPECT_EQ(0, server->Listen(5));
600
601 // Attempt connection.
602 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
603
604 // Accept connection.
605 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700606 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000607 ASSERT_TRUE(accepted);
608 sink.Monitor(accepted.get());
609
610 // Both sides are now connected.
611 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
612 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
613 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
614 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
615
616 // Send data to the client, and then close the connection.
617 accepted->Close();
618 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
619
620 // Expect that the client is notified, and has not yet closed.
621 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
622 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
623
624 // Now we should be closed and invalidated
625 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
626 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
627 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
628}
629
630class Sleeper : public MessageHandler {
631 public:
632 Sleeper() {}
633 void OnMessage(Message* msg) {
634 Thread::Current()->SleepMs(500);
635 }
636};
637
638void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
639 testing::StreamSink sink;
640 SocketAddress accept_addr;
641
642 // Create & connect server and client sockets.
jbauch555604a2016-04-26 03:13:22 -0700643 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000644 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauch555604a2016-04-26 03:13:22 -0700645 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000646 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
647 sink.Monitor(client.get());
648 sink.Monitor(server.get());
649 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
650 EXPECT_EQ(0, server->Listen(5));
651
652 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
653 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
654
jbauch555604a2016-04-26 03:13:22 -0700655 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000656 ASSERT_TRUE(accepted);
657 sink.Monitor(accepted.get());
658 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
659 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
660 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
661
662 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
663 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
664 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
665 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
666 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
667
668 // Do an i/o operation, triggering an eventual callback.
669 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
670 char buf[1024] = {0};
671
672 EXPECT_EQ(1024, client->Send(buf, 1024));
673 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
674
675 // Shouldn't signal when blocked in a thread Send, where process_io is false.
jbauch555604a2016-04-26 03:13:22 -0700676 std::unique_ptr<Thread> thread(new Thread());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000677 thread->Start();
678 Sleeper sleeper;
679 TypedMessageData<AsyncSocket*> data(client.get());
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700680 thread->Send(RTC_FROM_HERE, &sleeper, 0, &data);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000681 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
682
683 // But should signal when process_io is true.
684 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), testing::SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200685 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000686}
687
jbauchf2a2bf42016-02-03 16:45:32 -0800688void SocketTest::TcpInternal(const IPAddress& loopback, size_t data_size,
danilchapb7b9dca2016-08-05 05:55:43 -0700689 ptrdiff_t max_send_size) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000690 testing::StreamSink sink;
691 SocketAddress accept_addr;
692
jbauchf2a2bf42016-02-03 16:45:32 -0800693 // Create receiving client.
jbauch555604a2016-04-26 03:13:22 -0700694 std::unique_ptr<AsyncSocket> receiver(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000695 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800696 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000697
698 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700699 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000700 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
701 sink.Monitor(server.get());
702 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
703 EXPECT_EQ(0, server->Listen(5));
704
705 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800706 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000707
jbauchf2a2bf42016-02-03 16:45:32 -0800708 // Accept connection which will be used for sending.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000709 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700710 std::unique_ptr<AsyncSocket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800711 ASSERT_TRUE(sender);
712 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000713
714 // Both sides are now connected.
jbauchf2a2bf42016-02-03 16:45:32 -0800715 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, receiver->GetState(), kTimeout);
716 EXPECT_TRUE(sink.Check(receiver.get(), testing::SSE_OPEN));
717 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
718 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
719
720 // Create test data.
721 rtc::Buffer send_buffer(0, data_size);
722 rtc::Buffer recv_buffer(0, data_size);
723 for (size_t i = 0; i < data_size; ++i) {
724 char ch = static_cast<char>(i % 256);
725 send_buffer.AppendData(&ch, sizeof(ch));
726 }
danilchapb7b9dca2016-08-05 05:55:43 -0700727 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000728
729 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800730 size_t sent_size = 0;
731 bool writable = true;
732 bool send_called = false;
733 bool readable = false;
734 bool recv_called = false;
735 while (recv_buffer.size() < send_buffer.size()) {
736 // Send as much as we can while we're cleared to send.
737 while (writable && sent_size < send_buffer.size()) {
738 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
739 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
740 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000741 // The first Send() after connecting or getting writability should
742 // succeed and send some data.
743 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800744 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000745 }
746 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800747 EXPECT_LE(sent, unsent_size);
748 sent_size += sent;
749 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 05:55:43 -0700750 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-03 16:45:32 -0800751 if (sent < unsent_size) {
752 // If max_send_size is limiting the amount to send per call such
753 // that the sent amount is less than the unsent amount, we simulate
754 // that the socket is no longer writable.
755 writable = false;
756 }
757 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000758 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800759 ASSERT_TRUE(sender->IsBlocking());
760 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000761 }
762 }
763
764 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800765 while (recv_buffer.size() < sent_size) {
766 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000767 // Wait until data is available.
jbauchf2a2bf42016-02-03 16:45:32 -0800768 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), testing::SSE_READ),
769 kTimeout);
770 readable = true;
771 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000772 }
773
774 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 05:55:43 -0700775 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000776
jbauchf2a2bf42016-02-03 16:45:32 -0800777 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000778 // The first Recv() after getting readability should succeed and receive
779 // some data.
780 // TODO: The following line is disabled due to flakey pulse
781 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800782 // EXPECT_GT(recved_size, 0);
783 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000784 }
jbauchf2a2bf42016-02-03 16:45:32 -0800785 if (recved_size >= 0) {
786 EXPECT_LE(static_cast<size_t>(recved_size),
787 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 05:55:43 -0700788 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000789 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800790 ASSERT_TRUE(receiver->IsBlocking());
791 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000792 }
793 }
794
jbauchf2a2bf42016-02-03 16:45:32 -0800795 // Once all that we've sent has been received, expect to be able to send
796 // again.
797 if (!writable) {
danilchapb7b9dca2016-08-05 05:55:43 -0700798 ASSERT_TRUE_WAIT(sink.Check(sender.get(), testing::SSE_WRITE),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000799 kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800800 writable = true;
801 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000802 }
803 }
804
805 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800806 EXPECT_EQ(data_size, sent_size);
807 EXPECT_EQ(data_size, recv_buffer.size());
808 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000809
810 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800811 sender->Close();
812 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, receiver->GetState(), kTimeout);
813 EXPECT_TRUE(sink.Check(receiver.get(), testing::SSE_CLOSE));
814 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000815}
816
817void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
818 testing::StreamSink sink;
819 SocketAddress accept_addr;
820
821 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700822 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000823 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
824 sink.Monitor(client.get());
825
826 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700827 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000828 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
829 sink.Monitor(server.get());
830 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
831 EXPECT_EQ(0, server->Listen(5));
832
833 // Attempt connection.
834 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
835
836 // Accept connection.
837 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700838 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000839 ASSERT_TRUE(accepted);
840 sink.Monitor(accepted.get());
841
842 // Both sides are now connected.
843 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
844 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
845 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
846 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
847
848 // Expect a writable callback from the connect.
849 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
850
851 // Fill the socket buffer.
852 char buf[1024 * 16] = {0};
853 int sends = 0;
tfarina5237aaf2015-11-10 23:44:30 -0800854 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000855 EXPECT_TRUE(accepted->IsBlocking());
856
857 // Wait until data is available.
858 EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
859
860 // Pull data.
861 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200862 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000863 }
864
865 // Expect at least one additional writable callback.
866 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
867
868 // Adding data in response to the writeable callback shouldn't cause infinite
869 // callbacks.
870 int extras = 0;
871 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800872 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000873 rtc::Thread::Current()->ProcessMessages(1);
874 if (sink.Check(accepted.get(), testing::SSE_WRITE)) {
875 extras++;
876 }
877 }
878 EXPECT_LT(extras, 2);
879
880 // Close down.
881 accepted->Close();
882 client->Close();
883}
884
885void SocketTest::UdpInternal(const IPAddress& loopback) {
886 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
887 // Test basic bind and connect behavior.
888 AsyncSocket* socket =
889 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
890 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
891 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
892 SocketAddress addr1 = socket->GetLocalAddress();
893 EXPECT_EQ(0, socket->Connect(addr1));
894 EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
895 socket->Close();
896 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
897 delete socket;
898
899 // Test send/receive behavior.
jbauch555604a2016-04-26 03:13:22 -0700900 std::unique_ptr<TestClient> client1(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000901 new TestClient(AsyncUDPSocket::Create(ss_, addr1)));
jbauch555604a2016-04-26 03:13:22 -0700902 std::unique_ptr<TestClient> client2(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000903 new TestClient(AsyncUDPSocket::Create(ss_, empty)));
904
905 SocketAddress addr2;
906 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
907 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
908
909 SocketAddress addr3;
910 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
911 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
912 EXPECT_EQ(addr3, addr1);
913 // TODO: figure out what the intent is here
914 for (int i = 0; i < 10; ++i) {
915 client2.reset(new TestClient(AsyncUDPSocket::Create(ss_, empty)));
916
917 SocketAddress addr4;
918 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
919 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
920 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
921
922 SocketAddress addr5;
923 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
924 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
925 EXPECT_EQ(addr5, addr1);
926
927 addr2 = addr4;
928 }
929}
930
931void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
932 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
933 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
934 // documentation.
935 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
936 std::string dest = (loopback.family() == AF_INET6) ?
937 "2001:db8::1" : "192.0.2.0";
938 SocketAddress test_addr(dest, 2345);
939
940 // Test send
jbauch555604a2016-04-26 03:13:22 -0700941 std::unique_ptr<TestClient> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000942 new TestClient(AsyncUDPSocket::Create(ss_, empty)));
943 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -0700944 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000945 // Init the test packet just to avoid memcheck warning.
946 memset(test_packet.get(), 0, test_packet_size);
947 // Set the send buffer size to the same size as the test packet to have a
948 // better chance to get EWOULDBLOCK.
949 int send_buffer_size = test_packet_size;
950#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
951 send_buffer_size /= 2;
952#endif
953 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
954
955 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200956 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000957 int sent_packet_num = 0;
958 int expected_error = EWOULDBLOCK;
959 while (start_ms + kTimeout > Time()) {
960 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
961 ++sent_packet_num;
962 if (ret != test_packet_size) {
963 error = client->GetError();
964 if (error == expected_error) {
965 LOG(LS_INFO) << "Got expected error code after sending "
966 << sent_packet_num << " packets.";
967 break;
968 }
969 }
970 }
971 EXPECT_EQ(expected_error, error);
972 EXPECT_FALSE(client->ready_to_send());
973 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
974 LOG(LS_INFO) << "Got SignalReadyToSend";
975}
976
977void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
jbauch555604a2016-04-26 03:13:22 -0700978 std::unique_ptr<AsyncSocket> socket(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000979 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
980 socket->Bind(SocketAddress(loopback, 0));
981
982 // Check SNDBUF/RCVBUF.
983 const int desired_size = 12345;
984#if defined(WEBRTC_LINUX)
985 // Yes, really. It's in the kernel source.
986 const int expected_size = desired_size * 2;
987#else // !WEBRTC_LINUX
988 const int expected_size = desired_size;
989#endif // !WEBRTC_LINUX
990 int recv_size = 0;
991 int send_size = 0;
992 // get the initial sizes
993 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
994 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
995 // set our desired sizes
996 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
997 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
998 // get the sizes again
999 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1000 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1001 // make sure they are right
1002 ASSERT_EQ(expected_size, recv_size);
1003 ASSERT_EQ(expected_size, send_size);
1004
1005 // Check that we can't set NODELAY on a UDP socket.
1006 int current_nd, desired_nd = 1;
1007 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1008 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
1009
1010 // Skip the esimate MTU test for IPv6 for now.
1011 if (loopback.family() != AF_INET6) {
1012 // Try estimating MTU.
jbauch555604a2016-04-26 03:13:22 -07001013 std::unique_ptr<AsyncSocket> mtu_socket(
1014 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001015 mtu_socket->Bind(SocketAddress(loopback, 0));
Peter Boström0c4e06b2015-10-07 12:23:21 +02001016 uint16_t mtu;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001017 // should fail until we connect
1018 ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
1019 mtu_socket->Connect(SocketAddress(loopback, 0));
1020#if defined(WEBRTC_WIN)
1021 // now it should succeed
1022 ASSERT_NE(-1, mtu_socket->EstimateMTU(&mtu));
1023 ASSERT_GE(mtu, 1492); // should be at least the 1492 "plateau" on localhost
1024#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
1025 // except on WEBRTC_MAC && !WEBRTC_IOS, where it's not yet implemented
1026 ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
1027#else
1028 // and the behavior seems unpredictable on Linux,
1029 // failing on the build machine
1030 // but succeeding on my Ubiquity instance.
1031#endif
1032 }
1033}
1034
Stefan Holmer9131efd2016-05-23 18:19:26 +02001035void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
1036 std::unique_ptr<Socket> socket(
1037 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
1038 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1039 SocketAddress address = socket->GetLocalAddress();
1040
nissedeb95f32016-11-28 01:54:54 -08001041 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001042 socket->SendTo("foo", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001043 int64_t recv_timestamp_1;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001044 char buffer[3];
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001045 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1);
1046 EXPECT_GT(recv_timestamp_1, -1);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001047
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001048 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001049 Thread::SleepMs(kTimeBetweenPacketsMs);
1050
nissedeb95f32016-11-28 01:54:54 -08001051 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001052 socket->SendTo("bar", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001053 int64_t recv_timestamp_2;
1054 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2);
1055
1056 int64_t system_time_diff = send_time_2 - send_time_1;
1057 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1058 // Compare against the system time at the point of sending, because
1059 // SleepMs may not sleep for exactly the requested time.
1060 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001061}
1062
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001063} // namespace rtc