blob: 7d91cbefca04d57e4f83a99efd0940566cd6fe02 [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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "rtc_base/socket.h"
12
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <errno.h>
14#include <stdint.h>
15#include <string.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020016
jbauch555604a2016-04-26 03:13:22 -070017#include <memory>
18
Karl Wiberg918f50c2018-07-05 11:40:33 +020019#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "rtc_base/async_packet_socket.h"
22#include "rtc_base/async_socket.h"
23#include "rtc_base/async_udp_socket.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "rtc_base/buffer.h"
25#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 16:47:49 +010026#include "rtc_base/location.h"
27#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/message_handler.h"
29#include "rtc_base/message_queue.h"
30#include "rtc_base/net_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080031#include "rtc_base/socket_address.h"
32#include "rtc_base/socket_server.h"
Yves Gerey3e707812018-11-28 16:47:49 +010033#include "rtc_base/socket_unittest.h"
Steve Anton10542f22019-01-11 09:11:00 -080034#include "rtc_base/test_client.h"
35#include "rtc_base/test_utils.h"
Yves Gerey3e707812018-11-28 16:47:49 +010036#include "rtc_base/third_party/sigslot/sigslot.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020037#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080038#include "rtc_base/time_utils.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000039
40namespace rtc {
41
kwibergd0d81482017-04-18 03:18:22 -070042using webrtc::testing::SSE_CLOSE;
43using webrtc::testing::SSE_ERROR;
44using webrtc::testing::SSE_OPEN;
45using webrtc::testing::SSE_READ;
46using webrtc::testing::SSE_WRITE;
47using webrtc::testing::StreamSink;
48
Mirko Bonadei675513b2017-11-09 11:09:25 +010049#define MAYBE_SKIP_IPV6 \
50 if (!HasIPv6Enabled()) { \
51 RTC_LOG(LS_INFO) << "No IPv6... skipping"; \
52 return; \
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000053 }
54
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070055// Data size to be used in TcpInternal tests.
56static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000057
Steve Anton9de3aac2017-10-24 10:08:26 -070058void SocketTest::SetUp() {
59 ss_ = Thread::Current()->socketserver();
60}
61
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000062void SocketTest::TestConnectIPv4() {
63 ConnectInternal(kIPv4Loopback);
64}
65
66void SocketTest::TestConnectIPv6() {
67 MAYBE_SKIP_IPV6;
68 ConnectInternal(kIPv6Loopback);
69}
70
71void SocketTest::TestConnectWithDnsLookupIPv4() {
72 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
73}
74
75void SocketTest::TestConnectWithDnsLookupIPv6() {
76 // TODO: Enable this when DNS resolution supports IPv6.
Mirko Bonadei675513b2017-11-09 11:09:25 +010077 RTC_LOG(LS_INFO) << "Skipping IPv6 DNS test";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000078 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
79}
80
81void SocketTest::TestConnectFailIPv4() {
82 ConnectFailInternal(kIPv4Loopback);
83}
84
85void SocketTest::TestConnectFailIPv6() {
86 MAYBE_SKIP_IPV6;
87 ConnectFailInternal(kIPv6Loopback);
88}
89
90void SocketTest::TestConnectWithDnsLookupFailIPv4() {
91 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
92}
93
94void SocketTest::TestConnectWithDnsLookupFailIPv6() {
95 MAYBE_SKIP_IPV6;
96 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
97}
98
99void SocketTest::TestConnectWithClosedSocketIPv4() {
100 ConnectWithClosedSocketInternal(kIPv4Loopback);
101}
102
103void SocketTest::TestConnectWithClosedSocketIPv6() {
104 MAYBE_SKIP_IPV6;
105 ConnectWithClosedSocketInternal(kIPv6Loopback);
106}
107
108void SocketTest::TestConnectWhileNotClosedIPv4() {
109 ConnectWhileNotClosedInternal(kIPv4Loopback);
110}
111
112void SocketTest::TestConnectWhileNotClosedIPv6() {
113 MAYBE_SKIP_IPV6;
114 ConnectWhileNotClosedInternal(kIPv6Loopback);
115}
116
117void SocketTest::TestServerCloseDuringConnectIPv4() {
118 ServerCloseDuringConnectInternal(kIPv4Loopback);
119}
120
121void SocketTest::TestServerCloseDuringConnectIPv6() {
122 MAYBE_SKIP_IPV6;
123 ServerCloseDuringConnectInternal(kIPv6Loopback);
124}
125
126void SocketTest::TestClientCloseDuringConnectIPv4() {
127 ClientCloseDuringConnectInternal(kIPv4Loopback);
128}
129
130void SocketTest::TestClientCloseDuringConnectIPv6() {
131 MAYBE_SKIP_IPV6;
132 ClientCloseDuringConnectInternal(kIPv6Loopback);
133}
134
135void SocketTest::TestServerCloseIPv4() {
136 ServerCloseInternal(kIPv4Loopback);
137}
138
139void SocketTest::TestServerCloseIPv6() {
140 MAYBE_SKIP_IPV6;
141 ServerCloseInternal(kIPv6Loopback);
142}
143
144void SocketTest::TestCloseInClosedCallbackIPv4() {
145 CloseInClosedCallbackInternal(kIPv4Loopback);
146}
147
148void SocketTest::TestCloseInClosedCallbackIPv6() {
149 MAYBE_SKIP_IPV6;
150 CloseInClosedCallbackInternal(kIPv6Loopback);
151}
152
153void SocketTest::TestSocketServerWaitIPv4() {
154 SocketServerWaitInternal(kIPv4Loopback);
155}
156
157void SocketTest::TestSocketServerWaitIPv6() {
158 MAYBE_SKIP_IPV6;
159 SocketServerWaitInternal(kIPv6Loopback);
160}
161
162void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800163 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000164}
165
166void SocketTest::TestTcpIPv6() {
167 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800168 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000169}
170
171void SocketTest::TestSingleFlowControlCallbackIPv4() {
172 SingleFlowControlCallbackInternal(kIPv4Loopback);
173}
174
175void SocketTest::TestSingleFlowControlCallbackIPv6() {
176 MAYBE_SKIP_IPV6;
177 SingleFlowControlCallbackInternal(kIPv6Loopback);
178}
179
180void SocketTest::TestUdpIPv4() {
181 UdpInternal(kIPv4Loopback);
182}
183
184void SocketTest::TestUdpIPv6() {
185 MAYBE_SKIP_IPV6;
186 UdpInternal(kIPv6Loopback);
187}
188
189void SocketTest::TestUdpReadyToSendIPv4() {
190#if !defined(WEBRTC_MAC)
191 // TODO(ronghuawu): Enable this test on mac/ios.
192 UdpReadyToSend(kIPv4Loopback);
193#endif
194}
195
196void SocketTest::TestUdpReadyToSendIPv6() {
197#if defined(WEBRTC_WIN)
198 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
199 MAYBE_SKIP_IPV6;
200 UdpReadyToSend(kIPv6Loopback);
201#endif
202}
203
204void SocketTest::TestGetSetOptionsIPv4() {
205 GetSetOptionsInternal(kIPv4Loopback);
206}
207
208void SocketTest::TestGetSetOptionsIPv6() {
209 MAYBE_SKIP_IPV6;
210 GetSetOptionsInternal(kIPv6Loopback);
211}
212
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700213void SocketTest::TestSocketRecvTimestampIPv4() {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200214 SocketRecvTimestamp(kIPv4Loopback);
215}
216
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700217void SocketTest::TestSocketRecvTimestampIPv6() {
218 MAYBE_SKIP_IPV6;
219 SocketRecvTimestamp(kIPv6Loopback);
220}
221
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000222// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
223// values on Windows, but an empty address of the same family on Linux/MacOS X.
224bool IsUnspecOrEmptyIP(const IPAddress& address) {
225#if !defined(WEBRTC_WIN)
226 return IPIsAny(address);
227#else
228 return address.family() == AF_UNSPEC;
229#endif
230}
231
232void SocketTest::ConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700233 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000234 SocketAddress accept_addr;
235
236 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700237 std::unique_ptr<AsyncSocket> client(
238 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000239 sink.Monitor(client.get());
240 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
Jonas Olssonabbe8412018-04-03 13:40:05 +0200241 EXPECT_TRUE(IsUnspecOrEmptyIP(client->GetLocalAddress().ipaddr()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000242
243 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700244 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000245 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
246 sink.Monitor(server.get());
247 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
248 EXPECT_EQ(0, server->Listen(5));
249 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
250
251 // Ensure no pending server connections, since we haven't done anything yet.
kwibergd0d81482017-04-18 03:18:22 -0700252 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800253 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000254 EXPECT_TRUE(accept_addr.IsNil());
255
256 // Attempt connect to listening socket.
257 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
258 EXPECT_FALSE(client->GetLocalAddress().IsNil());
259 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
260
261 // Client is connecting, outcome not yet determined.
262 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700263 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
264 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000265
266 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700267 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700268 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000269 ASSERT_TRUE(accepted);
270 EXPECT_FALSE(accept_addr.IsNil());
271 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
272
273 // Connected from server perspective, check the addresses are correct.
274 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
275 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
276 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
277
278 // Connected from client perspective, check the addresses are correct.
279 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700280 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
281 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000282 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
283 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
284}
285
286void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
287 const std::string& host) {
kwibergd0d81482017-04-18 03:18:22 -0700288 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000289 SocketAddress accept_addr;
290
291 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700292 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000293 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
294 sink.Monitor(client.get());
295
296 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700297 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000298 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
299 sink.Monitor(server.get());
300 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
301 EXPECT_EQ(0, server->Listen(5));
302
303 // Attempt connect to listening socket.
304 SocketAddress dns_addr(server->GetLocalAddress());
305 dns_addr.SetIP(host);
306 EXPECT_EQ(0, client->Connect(dns_addr));
307 // TODO: Bind when doing DNS lookup.
Yves Gerey665174f2018-06-19 15:03:05 +0200308 // EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000309
310 // Client is connecting, outcome not yet determined.
311 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700312 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
313 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000314
315 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700316 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700317 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000318 ASSERT_TRUE(accepted);
319 EXPECT_FALSE(accept_addr.IsNil());
320 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
321
322 // Connected from server perspective, check the addresses are correct.
323 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
324 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
325 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
326
327 // Connected from client perspective, check the addresses are correct.
328 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700329 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
330 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000331 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
332 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
333}
334
335void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700336 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000337 SocketAddress accept_addr;
338
339 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700340 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000341 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
342 sink.Monitor(client.get());
343
344 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700345 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000346 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
347 sink.Monitor(server.get());
348 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
349
350 // Attempt connect to a non-existent socket.
351 // We don't connect to the server socket created above, since on
352 // MacOS it takes about 75 seconds to get back an error!
353 SocketAddress bogus_addr(loopback, 65535);
354 EXPECT_EQ(0, client->Connect(bogus_addr));
355
356 // Wait for connection to fail (ECONNREFUSED).
357 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700358 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
359 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000360 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
361
362 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700363 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800364 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000365 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
366}
367
368void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700369 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000370 SocketAddress accept_addr;
371
372 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700373 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000374 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
375 sink.Monitor(client.get());
376
377 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700378 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000379 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
380 sink.Monitor(server.get());
381 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
382
383 // Attempt connect to a non-existent host.
384 // We don't connect to the server socket created above, since on
385 // MacOS it takes about 75 seconds to get back an error!
386 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
387 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
388
389 // Wait for connection to fail (EHOSTNOTFOUND).
390 bool dns_lookup_finished = false;
391 WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
392 dns_lookup_finished);
393 if (!dns_lookup_finished) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100394 RTC_LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
395 << "seconds.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000396 return;
397 }
398
399 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700400 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
401 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000402 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
403 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700404 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800405 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000406 EXPECT_TRUE(accept_addr.IsNil());
407}
408
409void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
410 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700411 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000412 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
413 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
414 EXPECT_EQ(0, server->Listen(5));
415
416 // Create a client and put in to CS_CLOSED state.
jbauch555604a2016-04-26 03:13:22 -0700417 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000418 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
419 EXPECT_EQ(0, client->Close());
420 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
421
422 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
423 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
424 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
425}
426
427void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
428 // Create server and listen.
kwibergd0d81482017-04-18 03:18:22 -0700429 StreamSink sink;
jbauch555604a2016-04-26 03:13:22 -0700430 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000431 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
432 sink.Monitor(server.get());
433 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
434 EXPECT_EQ(0, server->Listen(5));
435 // Create client, connect.
jbauch555604a2016-04-26 03:13:22 -0700436 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000437 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
438 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
439 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
440 // Try to connect again. Should fail, but not interfere with original attempt.
441 EXPECT_EQ(SOCKET_ERROR,
442 client->Connect(SocketAddress(server->GetLocalAddress())));
443
444 // Accept the original connection.
445 SocketAddress accept_addr;
kwibergd0d81482017-04-18 03:18:22 -0700446 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700447 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000448 ASSERT_TRUE(accepted);
449 EXPECT_FALSE(accept_addr.IsNil());
450
451 // Check the states and addresses.
452 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
453 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
454 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
455 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
456 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
457 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
458
459 // Try to connect again, to an unresolved hostname.
460 // Shouldn't break anything.
Yves Gerey665174f2018-06-19 15:03:05 +0200461 EXPECT_EQ(SOCKET_ERROR, client->Connect(SocketAddress(
462 "localhost", server->GetLocalAddress().port())));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000463 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
464 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
465 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
466 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
467}
468
469void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700470 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000471
472 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700473 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000474 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
475 sink.Monitor(client.get());
476
477 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700478 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000479 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
480 sink.Monitor(server.get());
481 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
482 EXPECT_EQ(0, server->Listen(5));
483
484 // Attempt connect to listening socket.
485 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
486
487 // Close down the server while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700488 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000489 server->Close();
490
491 // This should fail the connection for the client. Clean up.
492 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700493 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000494 client->Close();
495}
496
497void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700498 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000499 SocketAddress accept_addr;
500
501 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700502 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000503 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
504 sink.Monitor(client.get());
505
506 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700507 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000508 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
509 sink.Monitor(server.get());
510 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
511 EXPECT_EQ(0, server->Listen(5));
512
513 // Attempt connect to listening socket.
514 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
515
516 // Close down the client while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700517 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000518 client->Close();
519
520 // The connection should still be able to be accepted.
jbauch555604a2016-04-26 03:13:22 -0700521 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000522 ASSERT_TRUE(accepted);
523 sink.Monitor(accepted.get());
524 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
525
526 // The accepted socket should then close (possibly with err, timing-related)
527 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700528 EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE) ||
529 sink.Check(accepted.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000530
531 // The client should not get a close event.
kwibergd0d81482017-04-18 03:18:22 -0700532 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000533}
534
535void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700536 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000537 SocketAddress accept_addr;
538
539 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700540 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000541 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
542 sink.Monitor(client.get());
543
544 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700545 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000546 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
547 sink.Monitor(server.get());
548 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
549 EXPECT_EQ(0, server->Listen(5));
550
551 // Attempt connection.
552 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
553
554 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700555 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700556 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000557 ASSERT_TRUE(accepted);
558 sink.Monitor(accepted.get());
559
560 // Both sides are now connected.
561 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700562 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000563 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
564 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
565
566 // Send data to the client, and then close the connection.
567 EXPECT_EQ(1, accepted->Send("a", 1));
568 accepted->Close();
569 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
570
571 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700572 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
573 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000574 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
575
576 // Ensure the data can be read.
577 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200578 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000579 EXPECT_EQ('a', buffer[0]);
580
581 // Now we should close, but the remote address will remain.
582 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700583 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000584 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
585
586 // The closer should not get a close signal.
kwibergd0d81482017-04-18 03:18:22 -0700587 EXPECT_FALSE(sink.Check(accepted.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000588 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
589
590 // And the closee should only get a single signal.
591 Thread::Current()->ProcessMessages(0);
kwibergd0d81482017-04-18 03:18:22 -0700592 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000593
594 // Close down the client and ensure all is good.
595 client->Close();
kwibergd0d81482017-04-18 03:18:22 -0700596 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000597 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
598}
599
600class SocketCloser : public sigslot::has_slots<> {
601 public:
602 void OnClose(AsyncSocket* socket, int error) {
603 socket->Close(); // Deleting here would blow up the vector of handlers
604 // for the socket's signal.
605 }
606};
607
608void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700609 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000610 SocketCloser closer;
611 SocketAddress accept_addr;
612
613 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700614 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000615 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
616 sink.Monitor(client.get());
617 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
618
619 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700620 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000621 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
622 sink.Monitor(server.get());
623 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
624 EXPECT_EQ(0, server->Listen(5));
625
626 // Attempt connection.
627 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
628
629 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700630 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700631 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000632 ASSERT_TRUE(accepted);
633 sink.Monitor(accepted.get());
634
635 // Both sides are now connected.
636 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700637 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000638 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
639 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
640
641 // Send data to the client, and then close the connection.
642 accepted->Close();
643 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
644
645 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700646 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000647 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
648
649 // Now we should be closed and invalidated
650 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700651 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000652 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
653}
654
655class Sleeper : public MessageHandler {
656 public:
Steve Anton9de3aac2017-10-24 10:08:26 -0700657 void OnMessage(Message* msg) override { Thread::Current()->SleepMs(500); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000658};
659
660void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700661 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000662 SocketAddress accept_addr;
663
664 // Create & connect server and client sockets.
jbauch555604a2016-04-26 03:13:22 -0700665 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000666 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauch555604a2016-04-26 03:13:22 -0700667 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000668 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
669 sink.Monitor(client.get());
670 sink.Monitor(server.get());
671 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
672 EXPECT_EQ(0, server->Listen(5));
673
674 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
kwibergd0d81482017-04-18 03:18:22 -0700675 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000676
jbauch555604a2016-04-26 03:13:22 -0700677 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000678 ASSERT_TRUE(accepted);
679 sink.Monitor(accepted.get());
680 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
681 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
682 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
683
684 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700685 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
686 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000687 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
688 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
689
690 // Do an i/o operation, triggering an eventual callback.
kwibergd0d81482017-04-18 03:18:22 -0700691 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000692 char buf[1024] = {0};
693
694 EXPECT_EQ(1024, client->Send(buf, 1024));
kwibergd0d81482017-04-18 03:18:22 -0700695 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000696
697 // Shouldn't signal when blocked in a thread Send, where process_io is false.
tommie7251592017-07-14 14:44:46 -0700698 std::unique_ptr<Thread> thread(Thread::CreateWithSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000699 thread->Start();
700 Sleeper sleeper;
701 TypedMessageData<AsyncSocket*> data(client.get());
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700702 thread->Send(RTC_FROM_HERE, &sleeper, 0, &data);
kwibergd0d81482017-04-18 03:18:22 -0700703 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000704
705 // But should signal when process_io is true.
kwibergd0d81482017-04-18 03:18:22 -0700706 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200707 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000708}
709
Yves Gerey665174f2018-06-19 15:03:05 +0200710void SocketTest::TcpInternal(const IPAddress& loopback,
711 size_t data_size,
712 ptrdiff_t max_send_size) {
kwibergd0d81482017-04-18 03:18:22 -0700713 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000714 SocketAddress accept_addr;
715
jbauchf2a2bf42016-02-03 16:45:32 -0800716 // Create receiving client.
jbauch555604a2016-04-26 03:13:22 -0700717 std::unique_ptr<AsyncSocket> receiver(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000718 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800719 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000720
721 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700722 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000723 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
724 sink.Monitor(server.get());
725 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
726 EXPECT_EQ(0, server->Listen(5));
727
728 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800729 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000730
jbauchf2a2bf42016-02-03 16:45:32 -0800731 // Accept connection which will be used for sending.
kwibergd0d81482017-04-18 03:18:22 -0700732 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700733 std::unique_ptr<AsyncSocket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800734 ASSERT_TRUE(sender);
735 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000736
737 // Both sides are now connected.
jbauchf2a2bf42016-02-03 16:45:32 -0800738 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700739 EXPECT_TRUE(sink.Check(receiver.get(), SSE_OPEN));
jbauchf2a2bf42016-02-03 16:45:32 -0800740 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
741 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
742
743 // Create test data.
744 rtc::Buffer send_buffer(0, data_size);
745 rtc::Buffer recv_buffer(0, data_size);
746 for (size_t i = 0; i < data_size; ++i) {
747 char ch = static_cast<char>(i % 256);
748 send_buffer.AppendData(&ch, sizeof(ch));
749 }
danilchapb7b9dca2016-08-05 05:55:43 -0700750 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000751
752 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800753 size_t sent_size = 0;
754 bool writable = true;
755 bool send_called = false;
756 bool readable = false;
757 bool recv_called = false;
758 while (recv_buffer.size() < send_buffer.size()) {
759 // Send as much as we can while we're cleared to send.
760 while (writable && sent_size < send_buffer.size()) {
761 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
762 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
763 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000764 // The first Send() after connecting or getting writability should
765 // succeed and send some data.
766 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800767 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000768 }
769 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800770 EXPECT_LE(sent, unsent_size);
771 sent_size += sent;
772 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 05:55:43 -0700773 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-03 16:45:32 -0800774 if (sent < unsent_size) {
775 // If max_send_size is limiting the amount to send per call such
776 // that the sent amount is less than the unsent amount, we simulate
777 // that the socket is no longer writable.
778 writable = false;
779 }
780 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000781 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800782 ASSERT_TRUE(sender->IsBlocking());
783 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000784 }
785 }
786
787 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800788 while (recv_buffer.size() < sent_size) {
789 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000790 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700791 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), SSE_READ), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800792 readable = true;
793 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000794 }
795
796 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 05:55:43 -0700797 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000798
jbauchf2a2bf42016-02-03 16:45:32 -0800799 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000800 // The first Recv() after getting readability should succeed and receive
801 // some data.
802 // TODO: The following line is disabled due to flakey pulse
803 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800804 // EXPECT_GT(recved_size, 0);
805 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000806 }
jbauchf2a2bf42016-02-03 16:45:32 -0800807 if (recved_size >= 0) {
808 EXPECT_LE(static_cast<size_t>(recved_size),
Yves Gerey665174f2018-06-19 15:03:05 +0200809 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 05:55:43 -0700810 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000811 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800812 ASSERT_TRUE(receiver->IsBlocking());
813 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000814 }
815 }
816
jbauchf2a2bf42016-02-03 16:45:32 -0800817 // Once all that we've sent has been received, expect to be able to send
818 // again.
819 if (!writable) {
kwibergd0d81482017-04-18 03:18:22 -0700820 ASSERT_TRUE_WAIT(sink.Check(sender.get(), SSE_WRITE), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800821 writable = true;
822 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000823 }
824 }
825
826 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800827 EXPECT_EQ(data_size, sent_size);
828 EXPECT_EQ(data_size, recv_buffer.size());
829 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000830
831 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800832 sender->Close();
833 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700834 EXPECT_TRUE(sink.Check(receiver.get(), SSE_CLOSE));
jbauchf2a2bf42016-02-03 16:45:32 -0800835 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000836}
837
838void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700839 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000840 SocketAddress accept_addr;
841
842 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700843 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000844 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
845 sink.Monitor(client.get());
846
847 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700848 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000849 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
850 sink.Monitor(server.get());
851 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
852 EXPECT_EQ(0, server->Listen(5));
853
854 // Attempt connection.
855 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
856
857 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700858 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700859 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000860 ASSERT_TRUE(accepted);
861 sink.Monitor(accepted.get());
862
863 // Both sides are now connected.
864 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700865 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000866 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
867 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
868
869 // Expect a writable callback from the connect.
kwibergd0d81482017-04-18 03:18:22 -0700870 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000871
872 // Fill the socket buffer.
873 char buf[1024 * 16] = {0};
874 int sends = 0;
Yves Gerey665174f2018-06-19 15:03:05 +0200875 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {
876 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000877 EXPECT_TRUE(accepted->IsBlocking());
878
879 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700880 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000881
882 // Pull data.
883 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200884 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000885 }
886
887 // Expect at least one additional writable callback.
kwibergd0d81482017-04-18 03:18:22 -0700888 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000889
890 // Adding data in response to the writeable callback shouldn't cause infinite
891 // callbacks.
892 int extras = 0;
893 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800894 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000895 rtc::Thread::Current()->ProcessMessages(1);
kwibergd0d81482017-04-18 03:18:22 -0700896 if (sink.Check(accepted.get(), SSE_WRITE)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000897 extras++;
898 }
899 }
900 EXPECT_LT(extras, 2);
901
902 // Close down.
903 accepted->Close();
904 client->Close();
905}
906
907void SocketTest::UdpInternal(const IPAddress& loopback) {
908 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
909 // Test basic bind and connect behavior.
Yves Gerey665174f2018-06-19 15:03:05 +0200910 AsyncSocket* socket = ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000911 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
912 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
913 SocketAddress addr1 = socket->GetLocalAddress();
914 EXPECT_EQ(0, socket->Connect(addr1));
915 EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
916 socket->Close();
917 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
918 delete socket;
919
920 // Test send/receive behavior.
jbauch555604a2016-04-26 03:13:22 -0700921 std::unique_ptr<TestClient> client1(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200922 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, addr1))));
jbauch555604a2016-04-26 03:13:22 -0700923 std::unique_ptr<TestClient> client2(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200924 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000925
926 SocketAddress addr2;
927 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
928 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
929
930 SocketAddress addr3;
931 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
932 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
933 EXPECT_EQ(addr3, addr1);
934 // TODO: figure out what the intent is here
935 for (int i = 0; i < 10; ++i) {
nisse32f25052017-05-08 01:57:18 -0700936 client2.reset(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200937 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000938
939 SocketAddress addr4;
940 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
941 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
942 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
943
944 SocketAddress addr5;
945 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
946 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
947 EXPECT_EQ(addr5, addr1);
948
949 addr2 = addr4;
950 }
951}
952
953void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
954 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
955 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
956 // documentation.
957 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
Yves Gerey665174f2018-06-19 15:03:05 +0200958 std::string dest =
959 (loopback.family() == AF_INET6) ? "2001:db8::1" : "192.0.2.0";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000960 SocketAddress test_addr(dest, 2345);
961
962 // Test send
jbauch555604a2016-04-26 03:13:22 -0700963 std::unique_ptr<TestClient> client(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200964 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000965 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -0700966 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000967 // Init the test packet just to avoid memcheck warning.
968 memset(test_packet.get(), 0, test_packet_size);
969 // Set the send buffer size to the same size as the test packet to have a
970 // better chance to get EWOULDBLOCK.
971 int send_buffer_size = test_packet_size;
972#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
973 send_buffer_size /= 2;
974#endif
975 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
976
977 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200978 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000979 int sent_packet_num = 0;
980 int expected_error = EWOULDBLOCK;
981 while (start_ms + kTimeout > Time()) {
982 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
983 ++sent_packet_num;
984 if (ret != test_packet_size) {
985 error = client->GetError();
986 if (error == expected_error) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100987 RTC_LOG(LS_INFO) << "Got expected error code after sending "
988 << sent_packet_num << " packets.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000989 break;
990 }
991 }
992 }
993 EXPECT_EQ(expected_error, error);
994 EXPECT_FALSE(client->ready_to_send());
995 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100996 RTC_LOG(LS_INFO) << "Got SignalReadyToSend";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000997}
998
999void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
jbauch555604a2016-04-26 03:13:22 -07001000 std::unique_ptr<AsyncSocket> socket(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001001 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
1002 socket->Bind(SocketAddress(loopback, 0));
1003
1004 // Check SNDBUF/RCVBUF.
1005 const int desired_size = 12345;
1006#if defined(WEBRTC_LINUX)
1007 // Yes, really. It's in the kernel source.
1008 const int expected_size = desired_size * 2;
1009#else // !WEBRTC_LINUX
1010 const int expected_size = desired_size;
1011#endif // !WEBRTC_LINUX
1012 int recv_size = 0;
1013 int send_size = 0;
1014 // get the initial sizes
1015 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1016 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1017 // set our desired sizes
1018 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
1019 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
1020 // get the sizes again
1021 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1022 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1023 // make sure they are right
1024 ASSERT_EQ(expected_size, recv_size);
1025 ASSERT_EQ(expected_size, send_size);
1026
1027 // Check that we can't set NODELAY on a UDP socket.
1028 int current_nd, desired_nd = 1;
1029 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1030 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001031}
1032
Stefan Holmer9131efd2016-05-23 18:19:26 +02001033void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
1034 std::unique_ptr<Socket> socket(
1035 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
1036 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1037 SocketAddress address = socket->GetLocalAddress();
1038
nissedeb95f32016-11-28 01:54:54 -08001039 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001040 socket->SendTo("foo", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001041 int64_t recv_timestamp_1;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001042 char buffer[3];
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001043 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1);
1044 EXPECT_GT(recv_timestamp_1, -1);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001045
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001046 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001047 Thread::SleepMs(kTimeBetweenPacketsMs);
1048
nissedeb95f32016-11-28 01:54:54 -08001049 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001050 socket->SendTo("bar", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001051 int64_t recv_timestamp_2;
1052 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2);
1053
1054 int64_t system_time_diff = send_time_2 - send_time_1;
1055 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1056 // Compare against the system time at the point of sending, because
1057 // SleepMs may not sleep for exactly the requested time.
1058 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001059}
1060
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001061} // namespace rtc