blob: 5548c0262ecfca2726da74934df64ab57c4744de [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "rtc_base/socket_unittest.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000014
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "rtc_base/arraysize.h"
16#include "rtc_base/asyncudpsocket.h"
17#include "rtc_base/buffer.h"
18#include "rtc_base/gunit.h"
19#include "rtc_base/nethelpers.h"
20#include "rtc_base/ptr_util.h"
21#include "rtc_base/socketserver.h"
22#include "rtc_base/testclient.h"
23#include "rtc_base/testutils.h"
24#include "rtc_base/thread.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000025
26namespace rtc {
27
kwibergd0d81482017-04-18 03:18:22 -070028using webrtc::testing::SSE_CLOSE;
29using webrtc::testing::SSE_ERROR;
30using webrtc::testing::SSE_OPEN;
31using webrtc::testing::SSE_READ;
32using webrtc::testing::SSE_WRITE;
33using webrtc::testing::StreamSink;
34
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000035#define MAYBE_SKIP_IPV6 \
36 if (!HasIPv6Enabled()) { \
37 LOG(LS_INFO) << "No IPv6... skipping"; \
38 return; \
39 }
40
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070041// Data size to be used in TcpInternal tests.
42static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000043
44void SocketTest::TestConnectIPv4() {
45 ConnectInternal(kIPv4Loopback);
46}
47
48void SocketTest::TestConnectIPv6() {
49 MAYBE_SKIP_IPV6;
50 ConnectInternal(kIPv6Loopback);
51}
52
53void SocketTest::TestConnectWithDnsLookupIPv4() {
54 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
55}
56
57void SocketTest::TestConnectWithDnsLookupIPv6() {
58 // TODO: Enable this when DNS resolution supports IPv6.
59 LOG(LS_INFO) << "Skipping IPv6 DNS test";
60 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
61}
62
63void SocketTest::TestConnectFailIPv4() {
64 ConnectFailInternal(kIPv4Loopback);
65}
66
67void SocketTest::TestConnectFailIPv6() {
68 MAYBE_SKIP_IPV6;
69 ConnectFailInternal(kIPv6Loopback);
70}
71
72void SocketTest::TestConnectWithDnsLookupFailIPv4() {
73 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
74}
75
76void SocketTest::TestConnectWithDnsLookupFailIPv6() {
77 MAYBE_SKIP_IPV6;
78 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
79}
80
81void SocketTest::TestConnectWithClosedSocketIPv4() {
82 ConnectWithClosedSocketInternal(kIPv4Loopback);
83}
84
85void SocketTest::TestConnectWithClosedSocketIPv6() {
86 MAYBE_SKIP_IPV6;
87 ConnectWithClosedSocketInternal(kIPv6Loopback);
88}
89
90void SocketTest::TestConnectWhileNotClosedIPv4() {
91 ConnectWhileNotClosedInternal(kIPv4Loopback);
92}
93
94void SocketTest::TestConnectWhileNotClosedIPv6() {
95 MAYBE_SKIP_IPV6;
96 ConnectWhileNotClosedInternal(kIPv6Loopback);
97}
98
99void SocketTest::TestServerCloseDuringConnectIPv4() {
100 ServerCloseDuringConnectInternal(kIPv4Loopback);
101}
102
103void SocketTest::TestServerCloseDuringConnectIPv6() {
104 MAYBE_SKIP_IPV6;
105 ServerCloseDuringConnectInternal(kIPv6Loopback);
106}
107
108void SocketTest::TestClientCloseDuringConnectIPv4() {
109 ClientCloseDuringConnectInternal(kIPv4Loopback);
110}
111
112void SocketTest::TestClientCloseDuringConnectIPv6() {
113 MAYBE_SKIP_IPV6;
114 ClientCloseDuringConnectInternal(kIPv6Loopback);
115}
116
117void SocketTest::TestServerCloseIPv4() {
118 ServerCloseInternal(kIPv4Loopback);
119}
120
121void SocketTest::TestServerCloseIPv6() {
122 MAYBE_SKIP_IPV6;
123 ServerCloseInternal(kIPv6Loopback);
124}
125
126void SocketTest::TestCloseInClosedCallbackIPv4() {
127 CloseInClosedCallbackInternal(kIPv4Loopback);
128}
129
130void SocketTest::TestCloseInClosedCallbackIPv6() {
131 MAYBE_SKIP_IPV6;
132 CloseInClosedCallbackInternal(kIPv6Loopback);
133}
134
135void SocketTest::TestSocketServerWaitIPv4() {
136 SocketServerWaitInternal(kIPv4Loopback);
137}
138
139void SocketTest::TestSocketServerWaitIPv6() {
140 MAYBE_SKIP_IPV6;
141 SocketServerWaitInternal(kIPv6Loopback);
142}
143
144void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800145 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000146}
147
148void SocketTest::TestTcpIPv6() {
149 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800150 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000151}
152
153void SocketTest::TestSingleFlowControlCallbackIPv4() {
154 SingleFlowControlCallbackInternal(kIPv4Loopback);
155}
156
157void SocketTest::TestSingleFlowControlCallbackIPv6() {
158 MAYBE_SKIP_IPV6;
159 SingleFlowControlCallbackInternal(kIPv6Loopback);
160}
161
162void SocketTest::TestUdpIPv4() {
163 UdpInternal(kIPv4Loopback);
164}
165
166void SocketTest::TestUdpIPv6() {
167 MAYBE_SKIP_IPV6;
168 UdpInternal(kIPv6Loopback);
169}
170
171void SocketTest::TestUdpReadyToSendIPv4() {
172#if !defined(WEBRTC_MAC)
173 // TODO(ronghuawu): Enable this test on mac/ios.
174 UdpReadyToSend(kIPv4Loopback);
175#endif
176}
177
178void SocketTest::TestUdpReadyToSendIPv6() {
179#if defined(WEBRTC_WIN)
180 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
181 MAYBE_SKIP_IPV6;
182 UdpReadyToSend(kIPv6Loopback);
183#endif
184}
185
186void SocketTest::TestGetSetOptionsIPv4() {
187 GetSetOptionsInternal(kIPv4Loopback);
188}
189
190void SocketTest::TestGetSetOptionsIPv6() {
191 MAYBE_SKIP_IPV6;
192 GetSetOptionsInternal(kIPv6Loopback);
193}
194
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700195void SocketTest::TestSocketRecvTimestampIPv4() {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200196 SocketRecvTimestamp(kIPv4Loopback);
197}
198
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700199void SocketTest::TestSocketRecvTimestampIPv6() {
200 MAYBE_SKIP_IPV6;
201 SocketRecvTimestamp(kIPv6Loopback);
202}
203
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000204// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
205// values on Windows, but an empty address of the same family on Linux/MacOS X.
206bool IsUnspecOrEmptyIP(const IPAddress& address) {
207#if !defined(WEBRTC_WIN)
208 return IPIsAny(address);
209#else
210 return address.family() == AF_UNSPEC;
211#endif
212}
213
214void SocketTest::ConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700215 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000216 SocketAddress accept_addr;
217
218 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700219 std::unique_ptr<AsyncSocket> client(
220 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000221 sink.Monitor(client.get());
222 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
223 EXPECT_PRED1(IsUnspecOrEmptyIP, client->GetLocalAddress().ipaddr());
224
225 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700226 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000227 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
228 sink.Monitor(server.get());
229 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
230 EXPECT_EQ(0, server->Listen(5));
231 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
232
233 // Ensure no pending server connections, since we haven't done anything yet.
kwibergd0d81482017-04-18 03:18:22 -0700234 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800235 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000236 EXPECT_TRUE(accept_addr.IsNil());
237
238 // Attempt connect to listening socket.
239 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
240 EXPECT_FALSE(client->GetLocalAddress().IsNil());
241 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
242
243 // Client is connecting, outcome not yet determined.
244 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700245 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
246 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000247
248 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700249 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700250 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000251 ASSERT_TRUE(accepted);
252 EXPECT_FALSE(accept_addr.IsNil());
253 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
254
255 // Connected from server perspective, check the addresses are correct.
256 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
257 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
258 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
259
260 // Connected from client perspective, check the addresses are correct.
261 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700262 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
263 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000264 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
265 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
266}
267
268void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
269 const std::string& host) {
kwibergd0d81482017-04-18 03:18:22 -0700270 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000271 SocketAddress accept_addr;
272
273 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700274 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000275 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
276 sink.Monitor(client.get());
277
278 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700279 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000280 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
281 sink.Monitor(server.get());
282 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
283 EXPECT_EQ(0, server->Listen(5));
284
285 // Attempt connect to listening socket.
286 SocketAddress dns_addr(server->GetLocalAddress());
287 dns_addr.SetIP(host);
288 EXPECT_EQ(0, client->Connect(dns_addr));
289 // TODO: Bind when doing DNS lookup.
290 //EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
291
292 // Client is connecting, outcome not yet determined.
293 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700294 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
295 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000296
297 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700298 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700299 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000300 ASSERT_TRUE(accepted);
301 EXPECT_FALSE(accept_addr.IsNil());
302 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
303
304 // Connected from server perspective, check the addresses are correct.
305 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
306 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
307 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
308
309 // Connected from client perspective, check the addresses are correct.
310 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700311 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
312 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000313 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
314 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
315}
316
317void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700318 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000319 SocketAddress accept_addr;
320
321 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700322 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000323 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
324 sink.Monitor(client.get());
325
326 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700327 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000328 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
329 sink.Monitor(server.get());
330 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
331
332 // Attempt connect to a non-existent socket.
333 // We don't connect to the server socket created above, since on
334 // MacOS it takes about 75 seconds to get back an error!
335 SocketAddress bogus_addr(loopback, 65535);
336 EXPECT_EQ(0, client->Connect(bogus_addr));
337
338 // Wait for connection to fail (ECONNREFUSED).
339 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700340 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
341 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000342 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
343
344 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700345 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800346 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000347 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
348}
349
350void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700351 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000352 SocketAddress accept_addr;
353
354 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700355 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000356 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
357 sink.Monitor(client.get());
358
359 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700360 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000361 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
362 sink.Monitor(server.get());
363 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
364
365 // Attempt connect to a non-existent host.
366 // We don't connect to the server socket created above, since on
367 // MacOS it takes about 75 seconds to get back an error!
368 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
369 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
370
371 // Wait for connection to fail (EHOSTNOTFOUND).
372 bool dns_lookup_finished = false;
373 WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
374 dns_lookup_finished);
375 if (!dns_lookup_finished) {
376 LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
377 << "seconds.";
378 return;
379 }
380
381 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700382 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
383 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000384 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
385 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700386 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800387 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000388 EXPECT_TRUE(accept_addr.IsNil());
389}
390
391void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
392 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700393 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000394 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
395 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
396 EXPECT_EQ(0, server->Listen(5));
397
398 // Create a client and put in to CS_CLOSED state.
jbauch555604a2016-04-26 03:13:22 -0700399 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000400 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
401 EXPECT_EQ(0, client->Close());
402 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
403
404 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
405 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
406 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
407}
408
409void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
410 // Create server and listen.
kwibergd0d81482017-04-18 03:18:22 -0700411 StreamSink sink;
jbauch555604a2016-04-26 03:13:22 -0700412 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000413 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
414 sink.Monitor(server.get());
415 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
416 EXPECT_EQ(0, server->Listen(5));
417 // Create client, connect.
jbauch555604a2016-04-26 03:13:22 -0700418 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000419 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
420 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
421 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
422 // Try to connect again. Should fail, but not interfere with original attempt.
423 EXPECT_EQ(SOCKET_ERROR,
424 client->Connect(SocketAddress(server->GetLocalAddress())));
425
426 // Accept the original connection.
427 SocketAddress accept_addr;
kwibergd0d81482017-04-18 03:18:22 -0700428 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700429 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000430 ASSERT_TRUE(accepted);
431 EXPECT_FALSE(accept_addr.IsNil());
432
433 // Check the states and addresses.
434 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
435 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
436 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
437 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
438 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
439 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
440
441 // Try to connect again, to an unresolved hostname.
442 // Shouldn't break anything.
443 EXPECT_EQ(SOCKET_ERROR,
444 client->Connect(SocketAddress("localhost",
445 server->GetLocalAddress().port())));
446 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
447 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
448 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
449 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
450}
451
452void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700453 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000454
455 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700456 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000457 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
458 sink.Monitor(client.get());
459
460 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700461 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000462 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
463 sink.Monitor(server.get());
464 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
465 EXPECT_EQ(0, server->Listen(5));
466
467 // Attempt connect to listening socket.
468 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
469
470 // Close down the server while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700471 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000472 server->Close();
473
474 // This should fail the connection for the client. Clean up.
475 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700476 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000477 client->Close();
478}
479
480void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700481 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000482 SocketAddress accept_addr;
483
484 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700485 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000486 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
487 sink.Monitor(client.get());
488
489 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700490 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000491 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
492 sink.Monitor(server.get());
493 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
494 EXPECT_EQ(0, server->Listen(5));
495
496 // Attempt connect to listening socket.
497 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
498
499 // Close down the client while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700500 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000501 client->Close();
502
503 // The connection should still be able to be accepted.
jbauch555604a2016-04-26 03:13:22 -0700504 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000505 ASSERT_TRUE(accepted);
506 sink.Monitor(accepted.get());
507 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
508
509 // The accepted socket should then close (possibly with err, timing-related)
510 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700511 EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE) ||
512 sink.Check(accepted.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000513
514 // The client should not get a close event.
kwibergd0d81482017-04-18 03:18:22 -0700515 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000516}
517
518void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700519 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000520 SocketAddress accept_addr;
521
522 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700523 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000524 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
525 sink.Monitor(client.get());
526
527 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700528 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000529 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
530 sink.Monitor(server.get());
531 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
532 EXPECT_EQ(0, server->Listen(5));
533
534 // Attempt connection.
535 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
536
537 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700538 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700539 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000540 ASSERT_TRUE(accepted);
541 sink.Monitor(accepted.get());
542
543 // Both sides are now connected.
544 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700545 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000546 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
547 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
548
549 // Send data to the client, and then close the connection.
550 EXPECT_EQ(1, accepted->Send("a", 1));
551 accepted->Close();
552 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
553
554 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700555 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
556 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000557 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
558
559 // Ensure the data can be read.
560 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200561 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000562 EXPECT_EQ('a', buffer[0]);
563
564 // Now we should close, but the remote address will remain.
565 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700566 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000567 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
568
569 // The closer should not get a close signal.
kwibergd0d81482017-04-18 03:18:22 -0700570 EXPECT_FALSE(sink.Check(accepted.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000571 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
572
573 // And the closee should only get a single signal.
574 Thread::Current()->ProcessMessages(0);
kwibergd0d81482017-04-18 03:18:22 -0700575 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000576
577 // Close down the client and ensure all is good.
578 client->Close();
kwibergd0d81482017-04-18 03:18:22 -0700579 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000580 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
581}
582
583class SocketCloser : public sigslot::has_slots<> {
584 public:
585 void OnClose(AsyncSocket* socket, int error) {
586 socket->Close(); // Deleting here would blow up the vector of handlers
587 // for the socket's signal.
588 }
589};
590
591void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700592 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000593 SocketCloser closer;
594 SocketAddress accept_addr;
595
596 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700597 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000598 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
599 sink.Monitor(client.get());
600 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
601
602 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700603 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000604 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
605 sink.Monitor(server.get());
606 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
607 EXPECT_EQ(0, server->Listen(5));
608
609 // Attempt connection.
610 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
611
612 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700613 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700614 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000615 ASSERT_TRUE(accepted);
616 sink.Monitor(accepted.get());
617
618 // Both sides are now connected.
619 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700620 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000621 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
622 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
623
624 // Send data to the client, and then close the connection.
625 accepted->Close();
626 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
627
628 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700629 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000630 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
631
632 // Now we should be closed and invalidated
633 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700634 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000635 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
636}
637
638class Sleeper : public MessageHandler {
639 public:
640 Sleeper() {}
641 void OnMessage(Message* msg) {
642 Thread::Current()->SleepMs(500);
643 }
644};
645
646void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700647 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000648 SocketAddress accept_addr;
649
650 // Create & connect server and client sockets.
jbauch555604a2016-04-26 03:13:22 -0700651 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000652 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauch555604a2016-04-26 03:13:22 -0700653 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000654 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
655 sink.Monitor(client.get());
656 sink.Monitor(server.get());
657 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
658 EXPECT_EQ(0, server->Listen(5));
659
660 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
kwibergd0d81482017-04-18 03:18:22 -0700661 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000662
jbauch555604a2016-04-26 03:13:22 -0700663 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000664 ASSERT_TRUE(accepted);
665 sink.Monitor(accepted.get());
666 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
667 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
668 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
669
670 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700671 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
672 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000673 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
674 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
675
676 // Do an i/o operation, triggering an eventual callback.
kwibergd0d81482017-04-18 03:18:22 -0700677 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000678 char buf[1024] = {0};
679
680 EXPECT_EQ(1024, client->Send(buf, 1024));
kwibergd0d81482017-04-18 03:18:22 -0700681 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000682
683 // Shouldn't signal when blocked in a thread Send, where process_io is false.
tommie7251592017-07-14 14:44:46 -0700684 std::unique_ptr<Thread> thread(Thread::CreateWithSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000685 thread->Start();
686 Sleeper sleeper;
687 TypedMessageData<AsyncSocket*> data(client.get());
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700688 thread->Send(RTC_FROM_HERE, &sleeper, 0, &data);
kwibergd0d81482017-04-18 03:18:22 -0700689 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000690
691 // But should signal when process_io is true.
kwibergd0d81482017-04-18 03:18:22 -0700692 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200693 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000694}
695
jbauchf2a2bf42016-02-03 16:45:32 -0800696void SocketTest::TcpInternal(const IPAddress& loopback, size_t data_size,
danilchapb7b9dca2016-08-05 05:55:43 -0700697 ptrdiff_t max_send_size) {
kwibergd0d81482017-04-18 03:18:22 -0700698 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000699 SocketAddress accept_addr;
700
jbauchf2a2bf42016-02-03 16:45:32 -0800701 // Create receiving client.
jbauch555604a2016-04-26 03:13:22 -0700702 std::unique_ptr<AsyncSocket> receiver(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000703 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800704 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000705
706 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700707 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000708 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
709 sink.Monitor(server.get());
710 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
711 EXPECT_EQ(0, server->Listen(5));
712
713 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800714 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000715
jbauchf2a2bf42016-02-03 16:45:32 -0800716 // Accept connection which will be used for sending.
kwibergd0d81482017-04-18 03:18:22 -0700717 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700718 std::unique_ptr<AsyncSocket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800719 ASSERT_TRUE(sender);
720 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000721
722 // Both sides are now connected.
jbauchf2a2bf42016-02-03 16:45:32 -0800723 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700724 EXPECT_TRUE(sink.Check(receiver.get(), SSE_OPEN));
jbauchf2a2bf42016-02-03 16:45:32 -0800725 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
726 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
727
728 // Create test data.
729 rtc::Buffer send_buffer(0, data_size);
730 rtc::Buffer recv_buffer(0, data_size);
731 for (size_t i = 0; i < data_size; ++i) {
732 char ch = static_cast<char>(i % 256);
733 send_buffer.AppendData(&ch, sizeof(ch));
734 }
danilchapb7b9dca2016-08-05 05:55:43 -0700735 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000736
737 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800738 size_t sent_size = 0;
739 bool writable = true;
740 bool send_called = false;
741 bool readable = false;
742 bool recv_called = false;
743 while (recv_buffer.size() < send_buffer.size()) {
744 // Send as much as we can while we're cleared to send.
745 while (writable && sent_size < send_buffer.size()) {
746 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
747 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
748 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000749 // The first Send() after connecting or getting writability should
750 // succeed and send some data.
751 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800752 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000753 }
754 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800755 EXPECT_LE(sent, unsent_size);
756 sent_size += sent;
757 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 05:55:43 -0700758 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-03 16:45:32 -0800759 if (sent < unsent_size) {
760 // If max_send_size is limiting the amount to send per call such
761 // that the sent amount is less than the unsent amount, we simulate
762 // that the socket is no longer writable.
763 writable = false;
764 }
765 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000766 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800767 ASSERT_TRUE(sender->IsBlocking());
768 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000769 }
770 }
771
772 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800773 while (recv_buffer.size() < sent_size) {
774 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000775 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700776 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), SSE_READ), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800777 readable = true;
778 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000779 }
780
781 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 05:55:43 -0700782 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000783
jbauchf2a2bf42016-02-03 16:45:32 -0800784 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000785 // The first Recv() after getting readability should succeed and receive
786 // some data.
787 // TODO: The following line is disabled due to flakey pulse
788 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800789 // EXPECT_GT(recved_size, 0);
790 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000791 }
jbauchf2a2bf42016-02-03 16:45:32 -0800792 if (recved_size >= 0) {
793 EXPECT_LE(static_cast<size_t>(recved_size),
794 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 05:55:43 -0700795 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000796 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800797 ASSERT_TRUE(receiver->IsBlocking());
798 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000799 }
800 }
801
jbauchf2a2bf42016-02-03 16:45:32 -0800802 // Once all that we've sent has been received, expect to be able to send
803 // again.
804 if (!writable) {
kwibergd0d81482017-04-18 03:18:22 -0700805 ASSERT_TRUE_WAIT(sink.Check(sender.get(), SSE_WRITE), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800806 writable = true;
807 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000808 }
809 }
810
811 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800812 EXPECT_EQ(data_size, sent_size);
813 EXPECT_EQ(data_size, recv_buffer.size());
814 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000815
816 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800817 sender->Close();
818 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700819 EXPECT_TRUE(sink.Check(receiver.get(), SSE_CLOSE));
jbauchf2a2bf42016-02-03 16:45:32 -0800820 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000821}
822
823void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700824 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000825 SocketAddress accept_addr;
826
827 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700828 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000829 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
830 sink.Monitor(client.get());
831
832 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700833 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000834 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
835 sink.Monitor(server.get());
836 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
837 EXPECT_EQ(0, server->Listen(5));
838
839 // Attempt connection.
840 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
841
842 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700843 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700844 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000845 ASSERT_TRUE(accepted);
846 sink.Monitor(accepted.get());
847
848 // Both sides are now connected.
849 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700850 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000851 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
852 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
853
854 // Expect a writable callback from the connect.
kwibergd0d81482017-04-18 03:18:22 -0700855 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000856
857 // Fill the socket buffer.
858 char buf[1024 * 16] = {0};
859 int sends = 0;
tfarina5237aaf2015-11-10 23:44:30 -0800860 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000861 EXPECT_TRUE(accepted->IsBlocking());
862
863 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700864 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000865
866 // Pull data.
867 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200868 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000869 }
870
871 // Expect at least one additional writable callback.
kwibergd0d81482017-04-18 03:18:22 -0700872 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000873
874 // Adding data in response to the writeable callback shouldn't cause infinite
875 // callbacks.
876 int extras = 0;
877 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800878 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000879 rtc::Thread::Current()->ProcessMessages(1);
kwibergd0d81482017-04-18 03:18:22 -0700880 if (sink.Check(accepted.get(), SSE_WRITE)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000881 extras++;
882 }
883 }
884 EXPECT_LT(extras, 2);
885
886 // Close down.
887 accepted->Close();
888 client->Close();
889}
890
891void SocketTest::UdpInternal(const IPAddress& loopback) {
892 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
893 // Test basic bind and connect behavior.
894 AsyncSocket* socket =
895 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
896 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
897 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
898 SocketAddress addr1 = socket->GetLocalAddress();
899 EXPECT_EQ(0, socket->Connect(addr1));
900 EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
901 socket->Close();
902 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
903 delete socket;
904
905 // Test send/receive behavior.
jbauch555604a2016-04-26 03:13:22 -0700906 std::unique_ptr<TestClient> client1(
nisse32f25052017-05-08 01:57:18 -0700907 new TestClient(WrapUnique(AsyncUDPSocket::Create(ss_, addr1))));
jbauch555604a2016-04-26 03:13:22 -0700908 std::unique_ptr<TestClient> client2(
nisse32f25052017-05-08 01:57:18 -0700909 new TestClient(WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000910
911 SocketAddress addr2;
912 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
913 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
914
915 SocketAddress addr3;
916 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
917 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
918 EXPECT_EQ(addr3, addr1);
919 // TODO: figure out what the intent is here
920 for (int i = 0; i < 10; ++i) {
nisse32f25052017-05-08 01:57:18 -0700921 client2.reset(
922 new TestClient(WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000923
924 SocketAddress addr4;
925 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
926 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
927 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
928
929 SocketAddress addr5;
930 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
931 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
932 EXPECT_EQ(addr5, addr1);
933
934 addr2 = addr4;
935 }
936}
937
938void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
939 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
940 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
941 // documentation.
942 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
943 std::string dest = (loopback.family() == AF_INET6) ?
944 "2001:db8::1" : "192.0.2.0";
945 SocketAddress test_addr(dest, 2345);
946
947 // Test send
jbauch555604a2016-04-26 03:13:22 -0700948 std::unique_ptr<TestClient> client(
nisse32f25052017-05-08 01:57:18 -0700949 new TestClient(WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000950 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -0700951 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000952 // Init the test packet just to avoid memcheck warning.
953 memset(test_packet.get(), 0, test_packet_size);
954 // Set the send buffer size to the same size as the test packet to have a
955 // better chance to get EWOULDBLOCK.
956 int send_buffer_size = test_packet_size;
957#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
958 send_buffer_size /= 2;
959#endif
960 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
961
962 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200963 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000964 int sent_packet_num = 0;
965 int expected_error = EWOULDBLOCK;
966 while (start_ms + kTimeout > Time()) {
967 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
968 ++sent_packet_num;
969 if (ret != test_packet_size) {
970 error = client->GetError();
971 if (error == expected_error) {
972 LOG(LS_INFO) << "Got expected error code after sending "
973 << sent_packet_num << " packets.";
974 break;
975 }
976 }
977 }
978 EXPECT_EQ(expected_error, error);
979 EXPECT_FALSE(client->ready_to_send());
980 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
981 LOG(LS_INFO) << "Got SignalReadyToSend";
982}
983
984void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
jbauch555604a2016-04-26 03:13:22 -0700985 std::unique_ptr<AsyncSocket> socket(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000986 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
987 socket->Bind(SocketAddress(loopback, 0));
988
989 // Check SNDBUF/RCVBUF.
990 const int desired_size = 12345;
991#if defined(WEBRTC_LINUX)
992 // Yes, really. It's in the kernel source.
993 const int expected_size = desired_size * 2;
994#else // !WEBRTC_LINUX
995 const int expected_size = desired_size;
996#endif // !WEBRTC_LINUX
997 int recv_size = 0;
998 int send_size = 0;
999 // get the initial sizes
1000 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1001 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1002 // set our desired sizes
1003 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
1004 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
1005 // get the sizes again
1006 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1007 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1008 // make sure they are right
1009 ASSERT_EQ(expected_size, recv_size);
1010 ASSERT_EQ(expected_size, send_size);
1011
1012 // Check that we can't set NODELAY on a UDP socket.
1013 int current_nd, desired_nd = 1;
1014 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1015 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001016}
1017
Stefan Holmer9131efd2016-05-23 18:19:26 +02001018void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
1019 std::unique_ptr<Socket> socket(
1020 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
1021 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1022 SocketAddress address = socket->GetLocalAddress();
1023
nissedeb95f32016-11-28 01:54:54 -08001024 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001025 socket->SendTo("foo", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001026 int64_t recv_timestamp_1;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001027 char buffer[3];
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001028 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1);
1029 EXPECT_GT(recv_timestamp_1, -1);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001030
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001031 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001032 Thread::SleepMs(kTimeBetweenPacketsMs);
1033
nissedeb95f32016-11-28 01:54:54 -08001034 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001035 socket->SendTo("bar", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001036 int64_t recv_timestamp_2;
1037 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2);
1038
1039 int64_t system_time_diff = send_time_2 - send_time_1;
1040 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1041 // Compare against the system time at the point of sending, because
1042 // SleepMs may not sleep for exactly the requested time.
1043 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001044}
1045
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001046} // namespace rtc