blob: ea37f23f27188d1fc706a001a80bdbd41bb02192 [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
Stefan Holmer9131efd2016-05-23 18:19:26 +0200187void SocketTest::TestSocketRecvTimestamp() {
188 SocketRecvTimestamp(kIPv4Loopback);
189}
190
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000191// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
192// values on Windows, but an empty address of the same family on Linux/MacOS X.
193bool IsUnspecOrEmptyIP(const IPAddress& address) {
194#if !defined(WEBRTC_WIN)
195 return IPIsAny(address);
196#else
197 return address.family() == AF_UNSPEC;
198#endif
199}
200
201void SocketTest::ConnectInternal(const IPAddress& loopback) {
202 testing::StreamSink sink;
203 SocketAddress accept_addr;
204
205 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700206 std::unique_ptr<AsyncSocket> client(
207 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000208 sink.Monitor(client.get());
209 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
210 EXPECT_PRED1(IsUnspecOrEmptyIP, client->GetLocalAddress().ipaddr());
211
212 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700213 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000214 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
215 sink.Monitor(server.get());
216 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
217 EXPECT_EQ(0, server->Listen(5));
218 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
219
220 // Ensure no pending server connections, since we haven't done anything yet.
221 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
222 EXPECT_TRUE(NULL == server->Accept(&accept_addr));
223 EXPECT_TRUE(accept_addr.IsNil());
224
225 // Attempt connect to listening socket.
226 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
227 EXPECT_FALSE(client->GetLocalAddress().IsNil());
228 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
229
230 // Client is connecting, outcome not yet determined.
231 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
232 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
233 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
234
235 // Server has pending connection, accept it.
236 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700237 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000238 ASSERT_TRUE(accepted);
239 EXPECT_FALSE(accept_addr.IsNil());
240 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
241
242 // Connected from server perspective, check the addresses are correct.
243 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
244 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
245 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
246
247 // Connected from client perspective, check the addresses are correct.
248 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
249 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
250 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
251 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
252 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
253}
254
255void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
256 const std::string& host) {
257 testing::StreamSink sink;
258 SocketAddress accept_addr;
259
260 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700261 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000262 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
263 sink.Monitor(client.get());
264
265 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700266 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000267 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
268 sink.Monitor(server.get());
269 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
270 EXPECT_EQ(0, server->Listen(5));
271
272 // Attempt connect to listening socket.
273 SocketAddress dns_addr(server->GetLocalAddress());
274 dns_addr.SetIP(host);
275 EXPECT_EQ(0, client->Connect(dns_addr));
276 // TODO: Bind when doing DNS lookup.
277 //EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
278
279 // Client is connecting, outcome not yet determined.
280 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
281 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
282 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
283
284 // Server has pending connection, accept it.
285 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700286 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000287 ASSERT_TRUE(accepted);
288 EXPECT_FALSE(accept_addr.IsNil());
289 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
290
291 // Connected from server perspective, check the addresses are correct.
292 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
293 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
294 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
295
296 // Connected from client perspective, check the addresses are correct.
297 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
298 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
299 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
300 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
301 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
302}
303
304void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
305 testing::StreamSink sink;
306 SocketAddress accept_addr;
307
308 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700309 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000310 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
311 sink.Monitor(client.get());
312
313 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700314 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000315 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
316 sink.Monitor(server.get());
317 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
318
319 // Attempt connect to a non-existent socket.
320 // We don't connect to the server socket created above, since on
321 // MacOS it takes about 75 seconds to get back an error!
322 SocketAddress bogus_addr(loopback, 65535);
323 EXPECT_EQ(0, client->Connect(bogus_addr));
324
325 // Wait for connection to fail (ECONNREFUSED).
326 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
327 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
328 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
329 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
330
331 // Should be no pending server connections.
332 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
333 EXPECT_TRUE(NULL == server->Accept(&accept_addr));
334 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
335}
336
337void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
338 testing::StreamSink sink;
339 SocketAddress accept_addr;
340
341 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700342 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000343 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
344 sink.Monitor(client.get());
345
346 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700347 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000348 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
349 sink.Monitor(server.get());
350 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
351
352 // Attempt connect to a non-existent host.
353 // We don't connect to the server socket created above, since on
354 // MacOS it takes about 75 seconds to get back an error!
355 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
356 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
357
358 // Wait for connection to fail (EHOSTNOTFOUND).
359 bool dns_lookup_finished = false;
360 WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
361 dns_lookup_finished);
362 if (!dns_lookup_finished) {
363 LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
364 << "seconds.";
365 return;
366 }
367
368 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
369 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
370 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
371 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
372 // Should be no pending server connections.
373 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
374 EXPECT_TRUE(NULL == server->Accept(&accept_addr));
375 EXPECT_TRUE(accept_addr.IsNil());
376}
377
378void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
379 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700380 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000381 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
382 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
383 EXPECT_EQ(0, server->Listen(5));
384
385 // Create a client and put in to CS_CLOSED state.
jbauch555604a2016-04-26 03:13:22 -0700386 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000387 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
388 EXPECT_EQ(0, client->Close());
389 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
390
391 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
392 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
393 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
394}
395
396void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
397 // Create server and listen.
398 testing::StreamSink sink;
jbauch555604a2016-04-26 03:13:22 -0700399 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000400 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
401 sink.Monitor(server.get());
402 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
403 EXPECT_EQ(0, server->Listen(5));
404 // Create client, connect.
jbauch555604a2016-04-26 03:13:22 -0700405 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000406 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
407 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
408 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
409 // Try to connect again. Should fail, but not interfere with original attempt.
410 EXPECT_EQ(SOCKET_ERROR,
411 client->Connect(SocketAddress(server->GetLocalAddress())));
412
413 // Accept the original connection.
414 SocketAddress accept_addr;
415 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700416 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000417 ASSERT_TRUE(accepted);
418 EXPECT_FALSE(accept_addr.IsNil());
419
420 // Check the states and addresses.
421 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
422 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
423 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
424 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
425 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
426 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
427
428 // Try to connect again, to an unresolved hostname.
429 // Shouldn't break anything.
430 EXPECT_EQ(SOCKET_ERROR,
431 client->Connect(SocketAddress("localhost",
432 server->GetLocalAddress().port())));
433 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
434 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
435 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
436 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
437}
438
439void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
440 testing::StreamSink sink;
441
442 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700443 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000444 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
445 sink.Monitor(client.get());
446
447 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700448 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000449 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
450 sink.Monitor(server.get());
451 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
452 EXPECT_EQ(0, server->Listen(5));
453
454 // Attempt connect to listening socket.
455 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
456
457 // Close down the server while the socket is in the accept queue.
458 EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
459 server->Close();
460
461 // This should fail the connection for the client. Clean up.
462 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
463 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
464 client->Close();
465}
466
467void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
468 testing::StreamSink sink;
469 SocketAddress accept_addr;
470
471 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700472 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000473 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
474 sink.Monitor(client.get());
475
476 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700477 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000478 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
479 sink.Monitor(server.get());
480 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
481 EXPECT_EQ(0, server->Listen(5));
482
483 // Attempt connect to listening socket.
484 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
485
486 // Close down the client while the socket is in the accept queue.
487 EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
488 client->Close();
489
490 // The connection should still be able to be accepted.
jbauch555604a2016-04-26 03:13:22 -0700491 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000492 ASSERT_TRUE(accepted);
493 sink.Monitor(accepted.get());
494 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
495
496 // The accepted socket should then close (possibly with err, timing-related)
497 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
498 EXPECT_TRUE(sink.Check(accepted.get(), testing::SSE_CLOSE) ||
499 sink.Check(accepted.get(), testing::SSE_ERROR));
500
501 // The client should not get a close event.
502 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
503}
504
505void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
506 testing::StreamSink sink;
507 SocketAddress accept_addr;
508
509 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700510 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000511 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
512 sink.Monitor(client.get());
513
514 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700515 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000516 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
517 sink.Monitor(server.get());
518 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
519 EXPECT_EQ(0, server->Listen(5));
520
521 // Attempt connection.
522 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
523
524 // Accept connection.
525 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700526 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000527 ASSERT_TRUE(accepted);
528 sink.Monitor(accepted.get());
529
530 // Both sides are now connected.
531 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
532 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
533 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
534 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
535
536 // Send data to the client, and then close the connection.
537 EXPECT_EQ(1, accepted->Send("a", 1));
538 accepted->Close();
539 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
540
541 // Expect that the client is notified, and has not yet closed.
542 EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
543 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
544 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
545
546 // Ensure the data can be read.
547 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200548 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000549 EXPECT_EQ('a', buffer[0]);
550
551 // Now we should close, but the remote address will remain.
552 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
553 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
554 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
555
556 // The closer should not get a close signal.
557 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_CLOSE));
558 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
559
560 // And the closee should only get a single signal.
561 Thread::Current()->ProcessMessages(0);
562 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
563
564 // Close down the client and ensure all is good.
565 client->Close();
566 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
567 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
568}
569
570class SocketCloser : public sigslot::has_slots<> {
571 public:
572 void OnClose(AsyncSocket* socket, int error) {
573 socket->Close(); // Deleting here would blow up the vector of handlers
574 // for the socket's signal.
575 }
576};
577
578void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
579 testing::StreamSink sink;
580 SocketCloser closer;
581 SocketAddress accept_addr;
582
583 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700584 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000585 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
586 sink.Monitor(client.get());
587 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
588
589 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700590 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000591 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
592 sink.Monitor(server.get());
593 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
594 EXPECT_EQ(0, server->Listen(5));
595
596 // Attempt connection.
597 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
598
599 // Accept connection.
600 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700601 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000602 ASSERT_TRUE(accepted);
603 sink.Monitor(accepted.get());
604
605 // Both sides are now connected.
606 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
607 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
608 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
609 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
610
611 // Send data to the client, and then close the connection.
612 accepted->Close();
613 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
614
615 // Expect that the client is notified, and has not yet closed.
616 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
617 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
618
619 // Now we should be closed and invalidated
620 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
621 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
622 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
623}
624
625class Sleeper : public MessageHandler {
626 public:
627 Sleeper() {}
628 void OnMessage(Message* msg) {
629 Thread::Current()->SleepMs(500);
630 }
631};
632
633void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
634 testing::StreamSink sink;
635 SocketAddress accept_addr;
636
637 // Create & connect server and client sockets.
jbauch555604a2016-04-26 03:13:22 -0700638 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000639 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauch555604a2016-04-26 03:13:22 -0700640 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000641 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
642 sink.Monitor(client.get());
643 sink.Monitor(server.get());
644 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
645 EXPECT_EQ(0, server->Listen(5));
646
647 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
648 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
649
jbauch555604a2016-04-26 03:13:22 -0700650 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000651 ASSERT_TRUE(accepted);
652 sink.Monitor(accepted.get());
653 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
654 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
655 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
656
657 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
658 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
659 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
660 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
661 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
662
663 // Do an i/o operation, triggering an eventual callback.
664 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
665 char buf[1024] = {0};
666
667 EXPECT_EQ(1024, client->Send(buf, 1024));
668 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
669
670 // Shouldn't signal when blocked in a thread Send, where process_io is false.
jbauch555604a2016-04-26 03:13:22 -0700671 std::unique_ptr<Thread> thread(new Thread());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000672 thread->Start();
673 Sleeper sleeper;
674 TypedMessageData<AsyncSocket*> data(client.get());
675 thread->Send(&sleeper, 0, &data);
676 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
677
678 // But should signal when process_io is true.
679 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), testing::SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200680 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000681}
682
jbauchf2a2bf42016-02-03 16:45:32 -0800683void SocketTest::TcpInternal(const IPAddress& loopback, size_t data_size,
684 ssize_t max_send_size) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000685 testing::StreamSink sink;
686 SocketAddress accept_addr;
687
jbauchf2a2bf42016-02-03 16:45:32 -0800688 // Create receiving client.
jbauch555604a2016-04-26 03:13:22 -0700689 std::unique_ptr<AsyncSocket> receiver(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000690 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800691 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000692
693 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700694 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000695 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.
jbauchf2a2bf42016-02-03 16:45:32 -0800701 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000702
jbauchf2a2bf42016-02-03 16:45:32 -0800703 // Accept connection which will be used for sending.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000704 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700705 std::unique_ptr<AsyncSocket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800706 ASSERT_TRUE(sender);
707 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000708
709 // Both sides are now connected.
jbauchf2a2bf42016-02-03 16:45:32 -0800710 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, receiver->GetState(), kTimeout);
711 EXPECT_TRUE(sink.Check(receiver.get(), testing::SSE_OPEN));
712 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
713 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
714
715 // Create test data.
716 rtc::Buffer send_buffer(0, data_size);
717 rtc::Buffer recv_buffer(0, data_size);
718 for (size_t i = 0; i < data_size; ++i) {
719 char ch = static_cast<char>(i % 256);
720 send_buffer.AppendData(&ch, sizeof(ch));
721 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000722
723 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800724 size_t sent_size = 0;
725 bool writable = true;
726 bool send_called = false;
727 bool readable = false;
728 bool recv_called = false;
729 while (recv_buffer.size() < send_buffer.size()) {
730 // Send as much as we can while we're cleared to send.
731 while (writable && sent_size < send_buffer.size()) {
732 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
733 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
734 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000735 // The first Send() after connecting or getting writability should
736 // succeed and send some data.
737 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800738 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000739 }
740 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800741 EXPECT_LE(sent, unsent_size);
742 sent_size += sent;
743 if (max_send_size >= 0) {
744 EXPECT_LE(static_cast<ssize_t>(sent), max_send_size);
745 if (sent < unsent_size) {
746 // If max_send_size is limiting the amount to send per call such
747 // that the sent amount is less than the unsent amount, we simulate
748 // that the socket is no longer writable.
749 writable = false;
750 }
751 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000752 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800753 ASSERT_TRUE(sender->IsBlocking());
754 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000755 }
756 }
757
758 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800759 while (recv_buffer.size() < sent_size) {
760 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000761 // Wait until data is available.
jbauchf2a2bf42016-02-03 16:45:32 -0800762 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), testing::SSE_READ),
763 kTimeout);
764 readable = true;
765 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000766 }
767
768 // Receive as much as we can get in a single recv call.
jbauchf2a2bf42016-02-03 16:45:32 -0800769 char recved_data[data_size];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200770 int recved_size = receiver->Recv(recved_data, data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000771
jbauchf2a2bf42016-02-03 16:45:32 -0800772 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000773 // The first Recv() after getting readability should succeed and receive
774 // some data.
775 // TODO: The following line is disabled due to flakey pulse
776 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800777 // EXPECT_GT(recved_size, 0);
778 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000779 }
jbauchf2a2bf42016-02-03 16:45:32 -0800780 if (recved_size >= 0) {
781 EXPECT_LE(static_cast<size_t>(recved_size),
782 sent_size - recv_buffer.size());
783 recv_buffer.AppendData(recved_data, recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000784 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800785 ASSERT_TRUE(receiver->IsBlocking());
786 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000787 }
788 }
789
jbauchf2a2bf42016-02-03 16:45:32 -0800790 // Once all that we've sent has been received, expect to be able to send
791 // again.
792 if (!writable) {
793 EXPECT_TRUE_WAIT(sink.Check(sender.get(), testing::SSE_WRITE),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000794 kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800795 writable = true;
796 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000797 }
798 }
799
800 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800801 EXPECT_EQ(data_size, sent_size);
802 EXPECT_EQ(data_size, recv_buffer.size());
803 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000804
805 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800806 sender->Close();
807 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, receiver->GetState(), kTimeout);
808 EXPECT_TRUE(sink.Check(receiver.get(), testing::SSE_CLOSE));
809 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000810}
811
812void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
813 testing::StreamSink sink;
814 SocketAddress accept_addr;
815
816 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700817 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000818 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
819 sink.Monitor(client.get());
820
821 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700822 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000823 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
824 sink.Monitor(server.get());
825 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
826 EXPECT_EQ(0, server->Listen(5));
827
828 // Attempt connection.
829 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
830
831 // Accept connection.
832 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700833 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000834 ASSERT_TRUE(accepted);
835 sink.Monitor(accepted.get());
836
837 // Both sides are now connected.
838 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
839 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
840 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
841 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
842
843 // Expect a writable callback from the connect.
844 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
845
846 // Fill the socket buffer.
847 char buf[1024 * 16] = {0};
848 int sends = 0;
tfarina5237aaf2015-11-10 23:44:30 -0800849 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000850 EXPECT_TRUE(accepted->IsBlocking());
851
852 // Wait until data is available.
853 EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
854
855 // Pull data.
856 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200857 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000858 }
859
860 // Expect at least one additional writable callback.
861 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
862
863 // Adding data in response to the writeable callback shouldn't cause infinite
864 // callbacks.
865 int extras = 0;
866 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800867 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000868 rtc::Thread::Current()->ProcessMessages(1);
869 if (sink.Check(accepted.get(), testing::SSE_WRITE)) {
870 extras++;
871 }
872 }
873 EXPECT_LT(extras, 2);
874
875 // Close down.
876 accepted->Close();
877 client->Close();
878}
879
880void SocketTest::UdpInternal(const IPAddress& loopback) {
881 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
882 // Test basic bind and connect behavior.
883 AsyncSocket* socket =
884 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
885 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
886 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
887 SocketAddress addr1 = socket->GetLocalAddress();
888 EXPECT_EQ(0, socket->Connect(addr1));
889 EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
890 socket->Close();
891 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
892 delete socket;
893
894 // Test send/receive behavior.
jbauch555604a2016-04-26 03:13:22 -0700895 std::unique_ptr<TestClient> client1(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000896 new TestClient(AsyncUDPSocket::Create(ss_, addr1)));
jbauch555604a2016-04-26 03:13:22 -0700897 std::unique_ptr<TestClient> client2(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000898 new TestClient(AsyncUDPSocket::Create(ss_, empty)));
899
900 SocketAddress addr2;
901 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
902 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
903
904 SocketAddress addr3;
905 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
906 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
907 EXPECT_EQ(addr3, addr1);
908 // TODO: figure out what the intent is here
909 for (int i = 0; i < 10; ++i) {
910 client2.reset(new TestClient(AsyncUDPSocket::Create(ss_, empty)));
911
912 SocketAddress addr4;
913 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
914 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
915 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
916
917 SocketAddress addr5;
918 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
919 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
920 EXPECT_EQ(addr5, addr1);
921
922 addr2 = addr4;
923 }
924}
925
926void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
927 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
928 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
929 // documentation.
930 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
931 std::string dest = (loopback.family() == AF_INET6) ?
932 "2001:db8::1" : "192.0.2.0";
933 SocketAddress test_addr(dest, 2345);
934
935 // Test send
jbauch555604a2016-04-26 03:13:22 -0700936 std::unique_ptr<TestClient> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000937 new TestClient(AsyncUDPSocket::Create(ss_, empty)));
938 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -0700939 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000940 // Init the test packet just to avoid memcheck warning.
941 memset(test_packet.get(), 0, test_packet_size);
942 // Set the send buffer size to the same size as the test packet to have a
943 // better chance to get EWOULDBLOCK.
944 int send_buffer_size = test_packet_size;
945#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
946 send_buffer_size /= 2;
947#endif
948 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
949
950 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200951 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000952 int sent_packet_num = 0;
953 int expected_error = EWOULDBLOCK;
954 while (start_ms + kTimeout > Time()) {
955 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
956 ++sent_packet_num;
957 if (ret != test_packet_size) {
958 error = client->GetError();
959 if (error == expected_error) {
960 LOG(LS_INFO) << "Got expected error code after sending "
961 << sent_packet_num << " packets.";
962 break;
963 }
964 }
965 }
966 EXPECT_EQ(expected_error, error);
967 EXPECT_FALSE(client->ready_to_send());
968 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
969 LOG(LS_INFO) << "Got SignalReadyToSend";
970}
971
972void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
jbauch555604a2016-04-26 03:13:22 -0700973 std::unique_ptr<AsyncSocket> socket(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000974 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
975 socket->Bind(SocketAddress(loopback, 0));
976
977 // Check SNDBUF/RCVBUF.
978 const int desired_size = 12345;
979#if defined(WEBRTC_LINUX)
980 // Yes, really. It's in the kernel source.
981 const int expected_size = desired_size * 2;
982#else // !WEBRTC_LINUX
983 const int expected_size = desired_size;
984#endif // !WEBRTC_LINUX
985 int recv_size = 0;
986 int send_size = 0;
987 // get the initial sizes
988 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
989 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
990 // set our desired sizes
991 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
992 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
993 // get the sizes again
994 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
995 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
996 // make sure they are right
997 ASSERT_EQ(expected_size, recv_size);
998 ASSERT_EQ(expected_size, send_size);
999
1000 // Check that we can't set NODELAY on a UDP socket.
1001 int current_nd, desired_nd = 1;
1002 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1003 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
1004
1005 // Skip the esimate MTU test for IPv6 for now.
1006 if (loopback.family() != AF_INET6) {
1007 // Try estimating MTU.
jbauch555604a2016-04-26 03:13:22 -07001008 std::unique_ptr<AsyncSocket> mtu_socket(
1009 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001010 mtu_socket->Bind(SocketAddress(loopback, 0));
Peter Boström0c4e06b2015-10-07 12:23:21 +02001011 uint16_t mtu;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001012 // should fail until we connect
1013 ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
1014 mtu_socket->Connect(SocketAddress(loopback, 0));
1015#if defined(WEBRTC_WIN)
1016 // now it should succeed
1017 ASSERT_NE(-1, mtu_socket->EstimateMTU(&mtu));
1018 ASSERT_GE(mtu, 1492); // should be at least the 1492 "plateau" on localhost
1019#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
1020 // except on WEBRTC_MAC && !WEBRTC_IOS, where it's not yet implemented
1021 ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
1022#else
1023 // and the behavior seems unpredictable on Linux,
1024 // failing on the build machine
1025 // but succeeding on my Ubiquity instance.
1026#endif
1027 }
1028}
1029
Stefan Holmer9131efd2016-05-23 18:19:26 +02001030void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
1031 std::unique_ptr<Socket> socket(
1032 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
1033 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1034 SocketAddress address = socket->GetLocalAddress();
1035
1036 socket->SendTo("foo", 3, address);
1037 int64_t timestamp;
1038 char buffer[3];
1039 socket->RecvFrom(buffer, 3, nullptr, &timestamp);
1040 EXPECT_GT(timestamp, -1);
1041 int64_t prev_timestamp = timestamp;
1042
1043 const int64_t kTimeBetweenPacketsMs = 10;
1044 Thread::SleepMs(kTimeBetweenPacketsMs);
1045
1046 socket->SendTo("bar", 3, address);
1047 socket->RecvFrom(buffer, 3, nullptr, &timestamp);
1048 EXPECT_NEAR(timestamp, prev_timestamp + kTimeBetweenPacketsMs * 1000, 2000);
1049}
1050
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001051} // namespace rtc