blob: 01ef014a6f75403ff859b672e8ae5236b90f0dc5 [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
Mirko Bonadei675513b2017-11-09 11:09:25 +010035#define MAYBE_SKIP_IPV6 \
36 if (!HasIPv6Enabled()) { \
37 RTC_LOG(LS_INFO) << "No IPv6... skipping"; \
38 return; \
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000039 }
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
Steve Anton9de3aac2017-10-24 10:08:26 -070044void SocketTest::SetUp() {
45 ss_ = Thread::Current()->socketserver();
46}
47
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000048void SocketTest::TestConnectIPv4() {
49 ConnectInternal(kIPv4Loopback);
50}
51
52void SocketTest::TestConnectIPv6() {
53 MAYBE_SKIP_IPV6;
54 ConnectInternal(kIPv6Loopback);
55}
56
57void SocketTest::TestConnectWithDnsLookupIPv4() {
58 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
59}
60
61void SocketTest::TestConnectWithDnsLookupIPv6() {
62 // TODO: Enable this when DNS resolution supports IPv6.
Mirko Bonadei675513b2017-11-09 11:09:25 +010063 RTC_LOG(LS_INFO) << "Skipping IPv6 DNS test";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000064 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
65}
66
67void SocketTest::TestConnectFailIPv4() {
68 ConnectFailInternal(kIPv4Loopback);
69}
70
71void SocketTest::TestConnectFailIPv6() {
72 MAYBE_SKIP_IPV6;
73 ConnectFailInternal(kIPv6Loopback);
74}
75
76void SocketTest::TestConnectWithDnsLookupFailIPv4() {
77 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
78}
79
80void SocketTest::TestConnectWithDnsLookupFailIPv6() {
81 MAYBE_SKIP_IPV6;
82 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
83}
84
85void SocketTest::TestConnectWithClosedSocketIPv4() {
86 ConnectWithClosedSocketInternal(kIPv4Loopback);
87}
88
89void SocketTest::TestConnectWithClosedSocketIPv6() {
90 MAYBE_SKIP_IPV6;
91 ConnectWithClosedSocketInternal(kIPv6Loopback);
92}
93
94void SocketTest::TestConnectWhileNotClosedIPv4() {
95 ConnectWhileNotClosedInternal(kIPv4Loopback);
96}
97
98void SocketTest::TestConnectWhileNotClosedIPv6() {
99 MAYBE_SKIP_IPV6;
100 ConnectWhileNotClosedInternal(kIPv6Loopback);
101}
102
103void SocketTest::TestServerCloseDuringConnectIPv4() {
104 ServerCloseDuringConnectInternal(kIPv4Loopback);
105}
106
107void SocketTest::TestServerCloseDuringConnectIPv6() {
108 MAYBE_SKIP_IPV6;
109 ServerCloseDuringConnectInternal(kIPv6Loopback);
110}
111
112void SocketTest::TestClientCloseDuringConnectIPv4() {
113 ClientCloseDuringConnectInternal(kIPv4Loopback);
114}
115
116void SocketTest::TestClientCloseDuringConnectIPv6() {
117 MAYBE_SKIP_IPV6;
118 ClientCloseDuringConnectInternal(kIPv6Loopback);
119}
120
121void SocketTest::TestServerCloseIPv4() {
122 ServerCloseInternal(kIPv4Loopback);
123}
124
125void SocketTest::TestServerCloseIPv6() {
126 MAYBE_SKIP_IPV6;
127 ServerCloseInternal(kIPv6Loopback);
128}
129
130void SocketTest::TestCloseInClosedCallbackIPv4() {
131 CloseInClosedCallbackInternal(kIPv4Loopback);
132}
133
134void SocketTest::TestCloseInClosedCallbackIPv6() {
135 MAYBE_SKIP_IPV6;
136 CloseInClosedCallbackInternal(kIPv6Loopback);
137}
138
139void SocketTest::TestSocketServerWaitIPv4() {
140 SocketServerWaitInternal(kIPv4Loopback);
141}
142
143void SocketTest::TestSocketServerWaitIPv6() {
144 MAYBE_SKIP_IPV6;
145 SocketServerWaitInternal(kIPv6Loopback);
146}
147
148void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800149 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000150}
151
152void SocketTest::TestTcpIPv6() {
153 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800154 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000155}
156
157void SocketTest::TestSingleFlowControlCallbackIPv4() {
158 SingleFlowControlCallbackInternal(kIPv4Loopback);
159}
160
161void SocketTest::TestSingleFlowControlCallbackIPv6() {
162 MAYBE_SKIP_IPV6;
163 SingleFlowControlCallbackInternal(kIPv6Loopback);
164}
165
166void SocketTest::TestUdpIPv4() {
167 UdpInternal(kIPv4Loopback);
168}
169
170void SocketTest::TestUdpIPv6() {
171 MAYBE_SKIP_IPV6;
172 UdpInternal(kIPv6Loopback);
173}
174
175void SocketTest::TestUdpReadyToSendIPv4() {
176#if !defined(WEBRTC_MAC)
177 // TODO(ronghuawu): Enable this test on mac/ios.
178 UdpReadyToSend(kIPv4Loopback);
179#endif
180}
181
182void SocketTest::TestUdpReadyToSendIPv6() {
183#if defined(WEBRTC_WIN)
184 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
185 MAYBE_SKIP_IPV6;
186 UdpReadyToSend(kIPv6Loopback);
187#endif
188}
189
190void SocketTest::TestGetSetOptionsIPv4() {
191 GetSetOptionsInternal(kIPv4Loopback);
192}
193
194void SocketTest::TestGetSetOptionsIPv6() {
195 MAYBE_SKIP_IPV6;
196 GetSetOptionsInternal(kIPv6Loopback);
197}
198
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700199void SocketTest::TestSocketRecvTimestampIPv4() {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200200 SocketRecvTimestamp(kIPv4Loopback);
201}
202
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700203void SocketTest::TestSocketRecvTimestampIPv6() {
204 MAYBE_SKIP_IPV6;
205 SocketRecvTimestamp(kIPv6Loopback);
206}
207
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000208// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
209// values on Windows, but an empty address of the same family on Linux/MacOS X.
210bool IsUnspecOrEmptyIP(const IPAddress& address) {
211#if !defined(WEBRTC_WIN)
212 return IPIsAny(address);
213#else
214 return address.family() == AF_UNSPEC;
215#endif
216}
217
218void SocketTest::ConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700219 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000220 SocketAddress accept_addr;
221
222 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700223 std::unique_ptr<AsyncSocket> client(
224 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000225 sink.Monitor(client.get());
226 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
Jonas Olssonabbe8412018-04-03 13:40:05 +0200227 EXPECT_TRUE(IsUnspecOrEmptyIP(client->GetLocalAddress().ipaddr()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000228
229 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700230 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000231 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
232 sink.Monitor(server.get());
233 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
234 EXPECT_EQ(0, server->Listen(5));
235 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
236
237 // Ensure no pending server connections, since we haven't done anything yet.
kwibergd0d81482017-04-18 03:18:22 -0700238 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800239 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000240 EXPECT_TRUE(accept_addr.IsNil());
241
242 // Attempt connect to listening socket.
243 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
244 EXPECT_FALSE(client->GetLocalAddress().IsNil());
245 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
246
247 // Client is connecting, outcome not yet determined.
248 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700249 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
250 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000251
252 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700253 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700254 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000255 ASSERT_TRUE(accepted);
256 EXPECT_FALSE(accept_addr.IsNil());
257 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
258
259 // Connected from server perspective, check the addresses are correct.
260 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
261 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
262 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
263
264 // Connected from client perspective, check the addresses are correct.
265 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700266 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
267 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000268 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
269 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
270}
271
272void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
273 const std::string& host) {
kwibergd0d81482017-04-18 03:18:22 -0700274 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000275 SocketAddress accept_addr;
276
277 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700278 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000279 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
280 sink.Monitor(client.get());
281
282 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700283 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000284 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
285 sink.Monitor(server.get());
286 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
287 EXPECT_EQ(0, server->Listen(5));
288
289 // Attempt connect to listening socket.
290 SocketAddress dns_addr(server->GetLocalAddress());
291 dns_addr.SetIP(host);
292 EXPECT_EQ(0, client->Connect(dns_addr));
293 // TODO: Bind when doing DNS lookup.
Yves Gerey665174f2018-06-19 15:03:05 +0200294 // EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000295
296 // Client is connecting, outcome not yet determined.
297 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700298 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
299 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000300
301 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700302 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700303 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000304 ASSERT_TRUE(accepted);
305 EXPECT_FALSE(accept_addr.IsNil());
306 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
307
308 // Connected from server perspective, check the addresses are correct.
309 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
310 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
311 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
312
313 // Connected from client perspective, check the addresses are correct.
314 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700315 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
316 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000317 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
318 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
319}
320
321void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700322 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000323 SocketAddress accept_addr;
324
325 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700326 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000327 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
328 sink.Monitor(client.get());
329
330 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700331 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000332 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
333 sink.Monitor(server.get());
334 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
335
336 // Attempt connect to a non-existent socket.
337 // We don't connect to the server socket created above, since on
338 // MacOS it takes about 75 seconds to get back an error!
339 SocketAddress bogus_addr(loopback, 65535);
340 EXPECT_EQ(0, client->Connect(bogus_addr));
341
342 // Wait for connection to fail (ECONNREFUSED).
343 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700344 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
345 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000346 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
347
348 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700349 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800350 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000351 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
352}
353
354void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700355 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000356 SocketAddress accept_addr;
357
358 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700359 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000360 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
361 sink.Monitor(client.get());
362
363 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700364 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000365 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
366 sink.Monitor(server.get());
367 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
368
369 // Attempt connect to a non-existent host.
370 // We don't connect to the server socket created above, since on
371 // MacOS it takes about 75 seconds to get back an error!
372 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
373 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
374
375 // Wait for connection to fail (EHOSTNOTFOUND).
376 bool dns_lookup_finished = false;
377 WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
378 dns_lookup_finished);
379 if (!dns_lookup_finished) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100380 RTC_LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
381 << "seconds.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000382 return;
383 }
384
385 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700386 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
387 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000388 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
389 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700390 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800391 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000392 EXPECT_TRUE(accept_addr.IsNil());
393}
394
395void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
396 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700397 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000398 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
399 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
400 EXPECT_EQ(0, server->Listen(5));
401
402 // Create a client and put in to CS_CLOSED state.
jbauch555604a2016-04-26 03:13:22 -0700403 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000404 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
405 EXPECT_EQ(0, client->Close());
406 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
407
408 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
409 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
410 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
411}
412
413void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
414 // Create server and listen.
kwibergd0d81482017-04-18 03:18:22 -0700415 StreamSink sink;
jbauch555604a2016-04-26 03:13:22 -0700416 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000417 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
418 sink.Monitor(server.get());
419 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
420 EXPECT_EQ(0, server->Listen(5));
421 // Create client, connect.
jbauch555604a2016-04-26 03:13:22 -0700422 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000423 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
424 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
425 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
426 // Try to connect again. Should fail, but not interfere with original attempt.
427 EXPECT_EQ(SOCKET_ERROR,
428 client->Connect(SocketAddress(server->GetLocalAddress())));
429
430 // Accept the original connection.
431 SocketAddress accept_addr;
kwibergd0d81482017-04-18 03:18:22 -0700432 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700433 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000434 ASSERT_TRUE(accepted);
435 EXPECT_FALSE(accept_addr.IsNil());
436
437 // Check the states and addresses.
438 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
439 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
440 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
441 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
442 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
443 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
444
445 // Try to connect again, to an unresolved hostname.
446 // Shouldn't break anything.
Yves Gerey665174f2018-06-19 15:03:05 +0200447 EXPECT_EQ(SOCKET_ERROR, client->Connect(SocketAddress(
448 "localhost", server->GetLocalAddress().port())));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000449 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
450 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
451 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
452 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
453}
454
455void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700456 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000457
458 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700459 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000460 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
461 sink.Monitor(client.get());
462
463 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700464 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000465 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
466 sink.Monitor(server.get());
467 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
468 EXPECT_EQ(0, server->Listen(5));
469
470 // Attempt connect to listening socket.
471 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
472
473 // Close down the server while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700474 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000475 server->Close();
476
477 // This should fail the connection for the client. Clean up.
478 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700479 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000480 client->Close();
481}
482
483void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700484 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000485 SocketAddress accept_addr;
486
487 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700488 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000489 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
490 sink.Monitor(client.get());
491
492 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700493 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000494 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
495 sink.Monitor(server.get());
496 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
497 EXPECT_EQ(0, server->Listen(5));
498
499 // Attempt connect to listening socket.
500 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
501
502 // Close down the client while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700503 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000504 client->Close();
505
506 // The connection should still be able to be accepted.
jbauch555604a2016-04-26 03:13:22 -0700507 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000508 ASSERT_TRUE(accepted);
509 sink.Monitor(accepted.get());
510 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
511
512 // The accepted socket should then close (possibly with err, timing-related)
513 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700514 EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE) ||
515 sink.Check(accepted.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000516
517 // The client should not get a close event.
kwibergd0d81482017-04-18 03:18:22 -0700518 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000519}
520
521void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700522 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000523 SocketAddress accept_addr;
524
525 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700526 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000527 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
528 sink.Monitor(client.get());
529
530 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700531 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000532 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
533 sink.Monitor(server.get());
534 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
535 EXPECT_EQ(0, server->Listen(5));
536
537 // Attempt connection.
538 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
539
540 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700541 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700542 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000543 ASSERT_TRUE(accepted);
544 sink.Monitor(accepted.get());
545
546 // Both sides are now connected.
547 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700548 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000549 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
550 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
551
552 // Send data to the client, and then close the connection.
553 EXPECT_EQ(1, accepted->Send("a", 1));
554 accepted->Close();
555 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
556
557 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700558 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
559 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000560 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
561
562 // Ensure the data can be read.
563 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200564 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000565 EXPECT_EQ('a', buffer[0]);
566
567 // Now we should close, but the remote address will remain.
568 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700569 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000570 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
571
572 // The closer should not get a close signal.
kwibergd0d81482017-04-18 03:18:22 -0700573 EXPECT_FALSE(sink.Check(accepted.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000574 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
575
576 // And the closee should only get a single signal.
577 Thread::Current()->ProcessMessages(0);
kwibergd0d81482017-04-18 03:18:22 -0700578 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000579
580 // Close down the client and ensure all is good.
581 client->Close();
kwibergd0d81482017-04-18 03:18:22 -0700582 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000583 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
584}
585
586class SocketCloser : public sigslot::has_slots<> {
587 public:
588 void OnClose(AsyncSocket* socket, int error) {
589 socket->Close(); // Deleting here would blow up the vector of handlers
590 // for the socket's signal.
591 }
592};
593
594void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700595 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000596 SocketCloser closer;
597 SocketAddress accept_addr;
598
599 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700600 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000601 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
602 sink.Monitor(client.get());
603 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
604
605 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700606 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000607 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
608 sink.Monitor(server.get());
609 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
610 EXPECT_EQ(0, server->Listen(5));
611
612 // Attempt connection.
613 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
614
615 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700616 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700617 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000618 ASSERT_TRUE(accepted);
619 sink.Monitor(accepted.get());
620
621 // Both sides are now connected.
622 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700623 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000624 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
625 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
626
627 // Send data to the client, and then close the connection.
628 accepted->Close();
629 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
630
631 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700632 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000633 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
634
635 // Now we should be closed and invalidated
636 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700637 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000638 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
639}
640
641class Sleeper : public MessageHandler {
642 public:
Steve Anton9de3aac2017-10-24 10:08:26 -0700643 void OnMessage(Message* msg) override { Thread::Current()->SleepMs(500); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000644};
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
Yves Gerey665174f2018-06-19 15:03:05 +0200696void SocketTest::TcpInternal(const IPAddress& loopback,
697 size_t data_size,
698 ptrdiff_t max_send_size) {
kwibergd0d81482017-04-18 03:18:22 -0700699 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000700 SocketAddress accept_addr;
701
jbauchf2a2bf42016-02-03 16:45:32 -0800702 // Create receiving client.
jbauch555604a2016-04-26 03:13:22 -0700703 std::unique_ptr<AsyncSocket> receiver(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000704 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800705 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000706
707 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700708 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000709 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
710 sink.Monitor(server.get());
711 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
712 EXPECT_EQ(0, server->Listen(5));
713
714 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800715 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000716
jbauchf2a2bf42016-02-03 16:45:32 -0800717 // Accept connection which will be used for sending.
kwibergd0d81482017-04-18 03:18:22 -0700718 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700719 std::unique_ptr<AsyncSocket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800720 ASSERT_TRUE(sender);
721 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000722
723 // Both sides are now connected.
jbauchf2a2bf42016-02-03 16:45:32 -0800724 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700725 EXPECT_TRUE(sink.Check(receiver.get(), SSE_OPEN));
jbauchf2a2bf42016-02-03 16:45:32 -0800726 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
727 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
728
729 // Create test data.
730 rtc::Buffer send_buffer(0, data_size);
731 rtc::Buffer recv_buffer(0, data_size);
732 for (size_t i = 0; i < data_size; ++i) {
733 char ch = static_cast<char>(i % 256);
734 send_buffer.AppendData(&ch, sizeof(ch));
735 }
danilchapb7b9dca2016-08-05 05:55:43 -0700736 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000737
738 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800739 size_t sent_size = 0;
740 bool writable = true;
741 bool send_called = false;
742 bool readable = false;
743 bool recv_called = false;
744 while (recv_buffer.size() < send_buffer.size()) {
745 // Send as much as we can while we're cleared to send.
746 while (writable && sent_size < send_buffer.size()) {
747 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
748 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
749 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000750 // The first Send() after connecting or getting writability should
751 // succeed and send some data.
752 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800753 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000754 }
755 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800756 EXPECT_LE(sent, unsent_size);
757 sent_size += sent;
758 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 05:55:43 -0700759 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-03 16:45:32 -0800760 if (sent < unsent_size) {
761 // If max_send_size is limiting the amount to send per call such
762 // that the sent amount is less than the unsent amount, we simulate
763 // that the socket is no longer writable.
764 writable = false;
765 }
766 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000767 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800768 ASSERT_TRUE(sender->IsBlocking());
769 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000770 }
771 }
772
773 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800774 while (recv_buffer.size() < sent_size) {
775 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000776 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700777 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), SSE_READ), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800778 readable = true;
779 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000780 }
781
782 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 05:55:43 -0700783 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000784
jbauchf2a2bf42016-02-03 16:45:32 -0800785 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000786 // The first Recv() after getting readability should succeed and receive
787 // some data.
788 // TODO: The following line is disabled due to flakey pulse
789 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800790 // EXPECT_GT(recved_size, 0);
791 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000792 }
jbauchf2a2bf42016-02-03 16:45:32 -0800793 if (recved_size >= 0) {
794 EXPECT_LE(static_cast<size_t>(recved_size),
Yves Gerey665174f2018-06-19 15:03:05 +0200795 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 05:55:43 -0700796 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000797 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800798 ASSERT_TRUE(receiver->IsBlocking());
799 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000800 }
801 }
802
jbauchf2a2bf42016-02-03 16:45:32 -0800803 // Once all that we've sent has been received, expect to be able to send
804 // again.
805 if (!writable) {
kwibergd0d81482017-04-18 03:18:22 -0700806 ASSERT_TRUE_WAIT(sink.Check(sender.get(), SSE_WRITE), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800807 writable = true;
808 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000809 }
810 }
811
812 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800813 EXPECT_EQ(data_size, sent_size);
814 EXPECT_EQ(data_size, recv_buffer.size());
815 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000816
817 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800818 sender->Close();
819 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700820 EXPECT_TRUE(sink.Check(receiver.get(), SSE_CLOSE));
jbauchf2a2bf42016-02-03 16:45:32 -0800821 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000822}
823
824void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700825 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000826 SocketAddress accept_addr;
827
828 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700829 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000830 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
831 sink.Monitor(client.get());
832
833 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700834 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000835 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
836 sink.Monitor(server.get());
837 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
838 EXPECT_EQ(0, server->Listen(5));
839
840 // Attempt connection.
841 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
842
843 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700844 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700845 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000846 ASSERT_TRUE(accepted);
847 sink.Monitor(accepted.get());
848
849 // Both sides are now connected.
850 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700851 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000852 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
853 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
854
855 // Expect a writable callback from the connect.
kwibergd0d81482017-04-18 03:18:22 -0700856 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000857
858 // Fill the socket buffer.
859 char buf[1024 * 16] = {0};
860 int sends = 0;
Yves Gerey665174f2018-06-19 15:03:05 +0200861 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {
862 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000863 EXPECT_TRUE(accepted->IsBlocking());
864
865 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700866 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000867
868 // Pull data.
869 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200870 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000871 }
872
873 // Expect at least one additional writable callback.
kwibergd0d81482017-04-18 03:18:22 -0700874 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000875
876 // Adding data in response to the writeable callback shouldn't cause infinite
877 // callbacks.
878 int extras = 0;
879 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800880 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000881 rtc::Thread::Current()->ProcessMessages(1);
kwibergd0d81482017-04-18 03:18:22 -0700882 if (sink.Check(accepted.get(), SSE_WRITE)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000883 extras++;
884 }
885 }
886 EXPECT_LT(extras, 2);
887
888 // Close down.
889 accepted->Close();
890 client->Close();
891}
892
893void SocketTest::UdpInternal(const IPAddress& loopback) {
894 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
895 // Test basic bind and connect behavior.
Yves Gerey665174f2018-06-19 15:03:05 +0200896 AsyncSocket* socket = ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000897 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
898 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
899 SocketAddress addr1 = socket->GetLocalAddress();
900 EXPECT_EQ(0, socket->Connect(addr1));
901 EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
902 socket->Close();
903 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
904 delete socket;
905
906 // Test send/receive behavior.
jbauch555604a2016-04-26 03:13:22 -0700907 std::unique_ptr<TestClient> client1(
nisse32f25052017-05-08 01:57:18 -0700908 new TestClient(WrapUnique(AsyncUDPSocket::Create(ss_, addr1))));
jbauch555604a2016-04-26 03:13:22 -0700909 std::unique_ptr<TestClient> client2(
nisse32f25052017-05-08 01:57:18 -0700910 new TestClient(WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000911
912 SocketAddress addr2;
913 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
914 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
915
916 SocketAddress addr3;
917 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
918 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
919 EXPECT_EQ(addr3, addr1);
920 // TODO: figure out what the intent is here
921 for (int i = 0; i < 10; ++i) {
nisse32f25052017-05-08 01:57:18 -0700922 client2.reset(
923 new TestClient(WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000924
925 SocketAddress addr4;
926 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
927 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
928 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
929
930 SocketAddress addr5;
931 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
932 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
933 EXPECT_EQ(addr5, addr1);
934
935 addr2 = addr4;
936 }
937}
938
939void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
940 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
941 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
942 // documentation.
943 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
Yves Gerey665174f2018-06-19 15:03:05 +0200944 std::string dest =
945 (loopback.family() == AF_INET6) ? "2001:db8::1" : "192.0.2.0";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000946 SocketAddress test_addr(dest, 2345);
947
948 // Test send
jbauch555604a2016-04-26 03:13:22 -0700949 std::unique_ptr<TestClient> client(
nisse32f25052017-05-08 01:57:18 -0700950 new TestClient(WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000951 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -0700952 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000953 // Init the test packet just to avoid memcheck warning.
954 memset(test_packet.get(), 0, test_packet_size);
955 // Set the send buffer size to the same size as the test packet to have a
956 // better chance to get EWOULDBLOCK.
957 int send_buffer_size = test_packet_size;
958#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
959 send_buffer_size /= 2;
960#endif
961 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
962
963 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200964 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000965 int sent_packet_num = 0;
966 int expected_error = EWOULDBLOCK;
967 while (start_ms + kTimeout > Time()) {
968 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
969 ++sent_packet_num;
970 if (ret != test_packet_size) {
971 error = client->GetError();
972 if (error == expected_error) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100973 RTC_LOG(LS_INFO) << "Got expected error code after sending "
974 << sent_packet_num << " packets.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000975 break;
976 }
977 }
978 }
979 EXPECT_EQ(expected_error, error);
980 EXPECT_FALSE(client->ready_to_send());
981 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100982 RTC_LOG(LS_INFO) << "Got SignalReadyToSend";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000983}
984
985void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
jbauch555604a2016-04-26 03:13:22 -0700986 std::unique_ptr<AsyncSocket> socket(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000987 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
988 socket->Bind(SocketAddress(loopback, 0));
989
990 // Check SNDBUF/RCVBUF.
991 const int desired_size = 12345;
992#if defined(WEBRTC_LINUX)
993 // Yes, really. It's in the kernel source.
994 const int expected_size = desired_size * 2;
995#else // !WEBRTC_LINUX
996 const int expected_size = desired_size;
997#endif // !WEBRTC_LINUX
998 int recv_size = 0;
999 int send_size = 0;
1000 // get the initial sizes
1001 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1002 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1003 // set our desired sizes
1004 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
1005 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
1006 // get the sizes again
1007 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1008 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1009 // make sure they are right
1010 ASSERT_EQ(expected_size, recv_size);
1011 ASSERT_EQ(expected_size, send_size);
1012
1013 // Check that we can't set NODELAY on a UDP socket.
1014 int current_nd, desired_nd = 1;
1015 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1016 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001017}
1018
Stefan Holmer9131efd2016-05-23 18:19:26 +02001019void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
1020 std::unique_ptr<Socket> socket(
1021 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
1022 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1023 SocketAddress address = socket->GetLocalAddress();
1024
nissedeb95f32016-11-28 01:54:54 -08001025 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001026 socket->SendTo("foo", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001027 int64_t recv_timestamp_1;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001028 char buffer[3];
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001029 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1);
1030 EXPECT_GT(recv_timestamp_1, -1);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001031
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001032 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001033 Thread::SleepMs(kTimeBetweenPacketsMs);
1034
nissedeb95f32016-11-28 01:54:54 -08001035 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001036 socket->SendTo("bar", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001037 int64_t recv_timestamp_2;
1038 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2);
1039
1040 int64_t system_time_diff = send_time_2 - send_time_1;
1041 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1042 // Compare against the system time at the point of sending, because
1043 // SleepMs may not sleep for exactly the requested time.
1044 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001045}
1046
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001047} // namespace rtc