blob: ac8509956c228b6e261fa16c6285201afaae62fd [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"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "rtc_base/net_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "rtc_base/socket_address.h"
31#include "rtc_base/socket_server.h"
Yves Gerey3e707812018-11-28 16:47:49 +010032#include "rtc_base/socket_unittest.h"
Steve Anton10542f22019-01-11 09:11:00 -080033#include "rtc_base/test_client.h"
34#include "rtc_base/test_utils.h"
Yves Gerey3e707812018-11-28 16:47:49 +010035#include "rtc_base/third_party/sigslot/sigslot.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020036#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080037#include "rtc_base/time_utils.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000038
39namespace rtc {
40
kwibergd0d81482017-04-18 03:18:22 -070041using webrtc::testing::SSE_CLOSE;
42using webrtc::testing::SSE_ERROR;
43using webrtc::testing::SSE_OPEN;
44using webrtc::testing::SSE_READ;
45using webrtc::testing::SSE_WRITE;
46using webrtc::testing::StreamSink;
47
Mirko Bonadei675513b2017-11-09 11:09:25 +010048#define MAYBE_SKIP_IPV6 \
49 if (!HasIPv6Enabled()) { \
50 RTC_LOG(LS_INFO) << "No IPv6... skipping"; \
51 return; \
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000052 }
53
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070054// Data size to be used in TcpInternal tests.
55static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000056
Steve Anton9de3aac2017-10-24 10:08:26 -070057void SocketTest::SetUp() {
58 ss_ = Thread::Current()->socketserver();
59}
60
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000061void SocketTest::TestConnectIPv4() {
62 ConnectInternal(kIPv4Loopback);
63}
64
65void SocketTest::TestConnectIPv6() {
66 MAYBE_SKIP_IPV6;
67 ConnectInternal(kIPv6Loopback);
68}
69
70void SocketTest::TestConnectWithDnsLookupIPv4() {
71 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
72}
73
74void SocketTest::TestConnectWithDnsLookupIPv6() {
75 // TODO: Enable this when DNS resolution supports IPv6.
Mirko Bonadei675513b2017-11-09 11:09:25 +010076 RTC_LOG(LS_INFO) << "Skipping IPv6 DNS test";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000077 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
78}
79
80void SocketTest::TestConnectFailIPv4() {
81 ConnectFailInternal(kIPv4Loopback);
82}
83
84void SocketTest::TestConnectFailIPv6() {
85 MAYBE_SKIP_IPV6;
86 ConnectFailInternal(kIPv6Loopback);
87}
88
89void SocketTest::TestConnectWithDnsLookupFailIPv4() {
90 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
91}
92
93void SocketTest::TestConnectWithDnsLookupFailIPv6() {
94 MAYBE_SKIP_IPV6;
95 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
96}
97
98void SocketTest::TestConnectWithClosedSocketIPv4() {
99 ConnectWithClosedSocketInternal(kIPv4Loopback);
100}
101
102void SocketTest::TestConnectWithClosedSocketIPv6() {
103 MAYBE_SKIP_IPV6;
104 ConnectWithClosedSocketInternal(kIPv6Loopback);
105}
106
107void SocketTest::TestConnectWhileNotClosedIPv4() {
108 ConnectWhileNotClosedInternal(kIPv4Loopback);
109}
110
111void SocketTest::TestConnectWhileNotClosedIPv6() {
112 MAYBE_SKIP_IPV6;
113 ConnectWhileNotClosedInternal(kIPv6Loopback);
114}
115
116void SocketTest::TestServerCloseDuringConnectIPv4() {
117 ServerCloseDuringConnectInternal(kIPv4Loopback);
118}
119
120void SocketTest::TestServerCloseDuringConnectIPv6() {
121 MAYBE_SKIP_IPV6;
122 ServerCloseDuringConnectInternal(kIPv6Loopback);
123}
124
125void SocketTest::TestClientCloseDuringConnectIPv4() {
126 ClientCloseDuringConnectInternal(kIPv4Loopback);
127}
128
129void SocketTest::TestClientCloseDuringConnectIPv6() {
130 MAYBE_SKIP_IPV6;
131 ClientCloseDuringConnectInternal(kIPv6Loopback);
132}
133
134void SocketTest::TestServerCloseIPv4() {
135 ServerCloseInternal(kIPv4Loopback);
136}
137
138void SocketTest::TestServerCloseIPv6() {
139 MAYBE_SKIP_IPV6;
140 ServerCloseInternal(kIPv6Loopback);
141}
142
143void SocketTest::TestCloseInClosedCallbackIPv4() {
144 CloseInClosedCallbackInternal(kIPv4Loopback);
145}
146
147void SocketTest::TestCloseInClosedCallbackIPv6() {
148 MAYBE_SKIP_IPV6;
149 CloseInClosedCallbackInternal(kIPv6Loopback);
150}
151
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000152void SocketTest::TestDeleteInReadCallbackIPv4() {
153 DeleteInReadCallbackInternal(kIPv4Loopback);
154}
155
156void SocketTest::TestDeleteInReadCallbackIPv6() {
157 MAYBE_SKIP_IPV6;
158 DeleteInReadCallbackInternal(kIPv6Loopback);
159}
160
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000161void SocketTest::TestSocketServerWaitIPv4() {
162 SocketServerWaitInternal(kIPv4Loopback);
163}
164
165void SocketTest::TestSocketServerWaitIPv6() {
166 MAYBE_SKIP_IPV6;
167 SocketServerWaitInternal(kIPv6Loopback);
168}
169
170void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800171 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000172}
173
174void SocketTest::TestTcpIPv6() {
175 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800176 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000177}
178
179void SocketTest::TestSingleFlowControlCallbackIPv4() {
180 SingleFlowControlCallbackInternal(kIPv4Loopback);
181}
182
183void SocketTest::TestSingleFlowControlCallbackIPv6() {
184 MAYBE_SKIP_IPV6;
185 SingleFlowControlCallbackInternal(kIPv6Loopback);
186}
187
188void SocketTest::TestUdpIPv4() {
189 UdpInternal(kIPv4Loopback);
190}
191
192void SocketTest::TestUdpIPv6() {
193 MAYBE_SKIP_IPV6;
194 UdpInternal(kIPv6Loopback);
195}
196
197void SocketTest::TestUdpReadyToSendIPv4() {
198#if !defined(WEBRTC_MAC)
199 // TODO(ronghuawu): Enable this test on mac/ios.
200 UdpReadyToSend(kIPv4Loopback);
201#endif
202}
203
204void SocketTest::TestUdpReadyToSendIPv6() {
205#if defined(WEBRTC_WIN)
206 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
207 MAYBE_SKIP_IPV6;
208 UdpReadyToSend(kIPv6Loopback);
209#endif
210}
211
212void SocketTest::TestGetSetOptionsIPv4() {
213 GetSetOptionsInternal(kIPv4Loopback);
214}
215
216void SocketTest::TestGetSetOptionsIPv6() {
217 MAYBE_SKIP_IPV6;
218 GetSetOptionsInternal(kIPv6Loopback);
219}
220
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700221void SocketTest::TestSocketRecvTimestampIPv4() {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200222 SocketRecvTimestamp(kIPv4Loopback);
223}
224
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700225void SocketTest::TestSocketRecvTimestampIPv6() {
226 MAYBE_SKIP_IPV6;
227 SocketRecvTimestamp(kIPv6Loopback);
228}
229
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000230// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
231// values on Windows, but an empty address of the same family on Linux/MacOS X.
232bool IsUnspecOrEmptyIP(const IPAddress& address) {
233#if !defined(WEBRTC_WIN)
234 return IPIsAny(address);
235#else
236 return address.family() == AF_UNSPEC;
237#endif
238}
239
240void SocketTest::ConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700241 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000242 SocketAddress accept_addr;
243
244 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700245 std::unique_ptr<AsyncSocket> client(
246 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000247 sink.Monitor(client.get());
248 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
Jonas Olssonabbe8412018-04-03 13:40:05 +0200249 EXPECT_TRUE(IsUnspecOrEmptyIP(client->GetLocalAddress().ipaddr()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000250
251 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700252 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000253 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
254 sink.Monitor(server.get());
255 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
256 EXPECT_EQ(0, server->Listen(5));
257 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
258
259 // Ensure no pending server connections, since we haven't done anything yet.
kwibergd0d81482017-04-18 03:18:22 -0700260 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800261 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000262 EXPECT_TRUE(accept_addr.IsNil());
263
264 // Attempt connect to listening socket.
265 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
266 EXPECT_FALSE(client->GetLocalAddress().IsNil());
267 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
268
269 // Client is connecting, outcome not yet determined.
270 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700271 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
272 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000273
274 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700275 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700276 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000277 ASSERT_TRUE(accepted);
278 EXPECT_FALSE(accept_addr.IsNil());
279 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
280
281 // Connected from server perspective, check the addresses are correct.
282 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
283 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
284 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
285
286 // Connected from client perspective, check the addresses are correct.
287 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700288 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
289 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000290 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
291 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
292}
293
294void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
295 const std::string& host) {
kwibergd0d81482017-04-18 03:18:22 -0700296 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000297 SocketAddress accept_addr;
298
299 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700300 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000301 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
302 sink.Monitor(client.get());
303
304 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700305 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000306 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
307 sink.Monitor(server.get());
308 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
309 EXPECT_EQ(0, server->Listen(5));
310
311 // Attempt connect to listening socket.
312 SocketAddress dns_addr(server->GetLocalAddress());
313 dns_addr.SetIP(host);
314 EXPECT_EQ(0, client->Connect(dns_addr));
315 // TODO: Bind when doing DNS lookup.
Yves Gerey665174f2018-06-19 15:03:05 +0200316 // EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000317
318 // Client is connecting, outcome not yet determined.
319 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700320 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
321 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000322
323 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700324 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700325 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000326 ASSERT_TRUE(accepted);
327 EXPECT_FALSE(accept_addr.IsNil());
328 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
329
330 // Connected from server perspective, check the addresses are correct.
331 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
332 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
333 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
334
335 // Connected from client perspective, check the addresses are correct.
336 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700337 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
338 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000339 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
340 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
341}
342
343void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700344 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000345 SocketAddress accept_addr;
346
347 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700348 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000349 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
350 sink.Monitor(client.get());
351
352 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700353 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000354 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
355 sink.Monitor(server.get());
356 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
357
358 // Attempt connect to a non-existent socket.
359 // We don't connect to the server socket created above, since on
360 // MacOS it takes about 75 seconds to get back an error!
361 SocketAddress bogus_addr(loopback, 65535);
362 EXPECT_EQ(0, client->Connect(bogus_addr));
363
364 // Wait for connection to fail (ECONNREFUSED).
365 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700366 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
367 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000368 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
369
370 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700371 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800372 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000373 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
374}
375
376void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700377 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000378 SocketAddress accept_addr;
379
380 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700381 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000382 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
383 sink.Monitor(client.get());
384
385 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700386 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000387 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
388 sink.Monitor(server.get());
389 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
390
391 // Attempt connect to a non-existent host.
392 // We don't connect to the server socket created above, since on
393 // MacOS it takes about 75 seconds to get back an error!
394 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
395 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
396
397 // Wait for connection to fail (EHOSTNOTFOUND).
398 bool dns_lookup_finished = false;
399 WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
400 dns_lookup_finished);
401 if (!dns_lookup_finished) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100402 RTC_LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
Jonas Olssonb2b20312020-01-14 12:11:31 +0100403 "seconds.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000404 return;
405 }
406
407 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700408 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
409 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000410 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
411 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700412 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800413 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000414 EXPECT_TRUE(accept_addr.IsNil());
415}
416
417void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
418 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700419 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000420 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
421 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
422 EXPECT_EQ(0, server->Listen(5));
423
424 // Create a client and put in to CS_CLOSED state.
jbauch555604a2016-04-26 03:13:22 -0700425 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000426 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
427 EXPECT_EQ(0, client->Close());
428 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
429
430 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
431 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
432 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
433}
434
435void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
436 // Create server and listen.
kwibergd0d81482017-04-18 03:18:22 -0700437 StreamSink sink;
jbauch555604a2016-04-26 03:13:22 -0700438 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000439 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
440 sink.Monitor(server.get());
441 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
442 EXPECT_EQ(0, server->Listen(5));
443 // Create client, connect.
jbauch555604a2016-04-26 03:13:22 -0700444 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000445 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
446 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
447 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
448 // Try to connect again. Should fail, but not interfere with original attempt.
449 EXPECT_EQ(SOCKET_ERROR,
450 client->Connect(SocketAddress(server->GetLocalAddress())));
451
452 // Accept the original connection.
453 SocketAddress accept_addr;
kwibergd0d81482017-04-18 03:18:22 -0700454 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700455 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000456 ASSERT_TRUE(accepted);
457 EXPECT_FALSE(accept_addr.IsNil());
458
459 // Check the states and addresses.
460 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
461 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
462 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
463 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
464 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
465 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
466
467 // Try to connect again, to an unresolved hostname.
468 // Shouldn't break anything.
Yves Gerey665174f2018-06-19 15:03:05 +0200469 EXPECT_EQ(SOCKET_ERROR, client->Connect(SocketAddress(
470 "localhost", server->GetLocalAddress().port())));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000471 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
472 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
473 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
474 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
475}
476
477void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700478 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000479
480 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700481 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000482 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
483 sink.Monitor(client.get());
484
485 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700486 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000487 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
488 sink.Monitor(server.get());
489 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
490 EXPECT_EQ(0, server->Listen(5));
491
492 // Attempt connect to listening socket.
493 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
494
495 // Close down the server while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700496 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000497 server->Close();
498
499 // This should fail the connection for the client. Clean up.
500 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700501 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000502 client->Close();
503}
504
505void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700506 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000507 SocketAddress accept_addr;
508
509 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700510 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000511 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
512 sink.Monitor(client.get());
513
514 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700515 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000516 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
517 sink.Monitor(server.get());
518 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
519 EXPECT_EQ(0, server->Listen(5));
520
521 // Attempt connect to listening socket.
522 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
523
524 // Close down the client while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700525 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000526 client->Close();
527
528 // The connection should still be able to be accepted.
jbauch555604a2016-04-26 03:13:22 -0700529 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000530 ASSERT_TRUE(accepted);
531 sink.Monitor(accepted.get());
532 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
533
534 // The accepted socket should then close (possibly with err, timing-related)
535 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700536 EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE) ||
537 sink.Check(accepted.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000538
539 // The client should not get a close event.
kwibergd0d81482017-04-18 03:18:22 -0700540 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000541}
542
543void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700544 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000545 SocketAddress accept_addr;
546
547 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700548 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000549 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
550 sink.Monitor(client.get());
551
552 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700553 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000554 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
555 sink.Monitor(server.get());
556 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
557 EXPECT_EQ(0, server->Listen(5));
558
559 // Attempt connection.
560 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
561
562 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700563 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700564 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000565 ASSERT_TRUE(accepted);
566 sink.Monitor(accepted.get());
567
568 // Both sides are now connected.
569 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700570 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000571 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
572 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
573
574 // Send data to the client, and then close the connection.
575 EXPECT_EQ(1, accepted->Send("a", 1));
576 accepted->Close();
577 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
578
579 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700580 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
581 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000582 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
583
584 // Ensure the data can be read.
585 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200586 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000587 EXPECT_EQ('a', buffer[0]);
588
589 // Now we should close, but the remote address will remain.
590 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700591 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000592 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
593
594 // The closer should not get a close signal.
kwibergd0d81482017-04-18 03:18:22 -0700595 EXPECT_FALSE(sink.Check(accepted.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000596 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
597
598 // And the closee should only get a single signal.
599 Thread::Current()->ProcessMessages(0);
kwibergd0d81482017-04-18 03:18:22 -0700600 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000601
602 // Close down the client and ensure all is good.
603 client->Close();
kwibergd0d81482017-04-18 03:18:22 -0700604 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000605 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
606}
607
608class SocketCloser : public sigslot::has_slots<> {
609 public:
610 void OnClose(AsyncSocket* socket, int error) {
611 socket->Close(); // Deleting here would blow up the vector of handlers
612 // for the socket's signal.
613 }
614};
615
616void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700617 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000618 SocketCloser closer;
619 SocketAddress accept_addr;
620
621 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700622 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000623 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
624 sink.Monitor(client.get());
625 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
626
627 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700628 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000629 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
630 sink.Monitor(server.get());
631 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
632 EXPECT_EQ(0, server->Listen(5));
633
634 // Attempt connection.
635 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
636
637 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700638 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700639 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000640 ASSERT_TRUE(accepted);
641 sink.Monitor(accepted.get());
642
643 // Both sides are now connected.
644 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700645 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000646 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
647 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
648
649 // Send data to the client, and then close the connection.
650 accepted->Close();
651 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
652
653 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700654 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000655 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
656
657 // Now we should be closed and invalidated
658 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700659 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000660 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
661}
662
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000663// Helper class specifically for the test below.
664class SocketDeleter : public sigslot::has_slots<> {
665 public:
666 explicit SocketDeleter(std::unique_ptr<AsyncSocket> socket)
667 : socket_(std::move(socket)) {}
668
669 void Delete(AsyncSocket* other) { socket_.reset(); }
670
671 bool deleted() const { return socket_ == nullptr; }
672
673 private:
674 std::unique_ptr<AsyncSocket> socket_;
675};
676
677// Tested deleting a socket within another socket's read callback. A previous
678// iteration of the select loop failed in this situation, if both sockets
679// became readable at the same time.
680void SocketTest::DeleteInReadCallbackInternal(const IPAddress& loopback) {
681 std::unique_ptr<AsyncSocket> socket1(
682 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
683 std::unique_ptr<AsyncSocket> socket2(
684 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
685 EXPECT_EQ(0, socket1->Bind(SocketAddress(loopback, 0)));
686 EXPECT_EQ(0, socket2->Bind(SocketAddress(loopback, 0)));
687 EXPECT_EQ(3, socket1->SendTo("foo", 3, socket1->GetLocalAddress()));
688 EXPECT_EQ(3, socket2->SendTo("bar", 3, socket1->GetLocalAddress()));
689 // Sleep a while to ensure sends are both completed at the same time.
690 Thread::SleepMs(1000);
691
692 // Configure the helper class to delete socket 2 when socket 1 has a read
693 // event.
694 SocketDeleter deleter(std::move(socket2));
695 socket1->SignalReadEvent.connect(&deleter, &SocketDeleter::Delete);
696 EXPECT_TRUE_WAIT(deleter.deleted(), kTimeout);
697}
698
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000699class Sleeper : public MessageHandler {
700 public:
Steve Anton9de3aac2017-10-24 10:08:26 -0700701 void OnMessage(Message* msg) override { Thread::Current()->SleepMs(500); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000702};
703
704void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700705 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000706 SocketAddress accept_addr;
707
708 // Create & connect server and client sockets.
jbauch555604a2016-04-26 03:13:22 -0700709 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000710 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauch555604a2016-04-26 03:13:22 -0700711 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000712 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
713 sink.Monitor(client.get());
714 sink.Monitor(server.get());
715 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
716 EXPECT_EQ(0, server->Listen(5));
717
718 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
kwibergd0d81482017-04-18 03:18:22 -0700719 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000720
jbauch555604a2016-04-26 03:13:22 -0700721 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000722 ASSERT_TRUE(accepted);
723 sink.Monitor(accepted.get());
724 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
725 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
726 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
727
728 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700729 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
730 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000731 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
732 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
733
734 // Do an i/o operation, triggering an eventual callback.
kwibergd0d81482017-04-18 03:18:22 -0700735 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000736 char buf[1024] = {0};
737
738 EXPECT_EQ(1024, client->Send(buf, 1024));
kwibergd0d81482017-04-18 03:18:22 -0700739 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000740
741 // Shouldn't signal when blocked in a thread Send, where process_io is false.
tommie7251592017-07-14 14:44:46 -0700742 std::unique_ptr<Thread> thread(Thread::CreateWithSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000743 thread->Start();
744 Sleeper sleeper;
745 TypedMessageData<AsyncSocket*> data(client.get());
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700746 thread->Send(RTC_FROM_HERE, &sleeper, 0, &data);
kwibergd0d81482017-04-18 03:18:22 -0700747 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000748
749 // But should signal when process_io is true.
kwibergd0d81482017-04-18 03:18:22 -0700750 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200751 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000752}
753
Yves Gerey665174f2018-06-19 15:03:05 +0200754void SocketTest::TcpInternal(const IPAddress& loopback,
755 size_t data_size,
756 ptrdiff_t max_send_size) {
kwibergd0d81482017-04-18 03:18:22 -0700757 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000758 SocketAddress accept_addr;
759
jbauchf2a2bf42016-02-03 16:45:32 -0800760 // Create receiving client.
jbauch555604a2016-04-26 03:13:22 -0700761 std::unique_ptr<AsyncSocket> receiver(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000762 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800763 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000764
765 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700766 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000767 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
768 sink.Monitor(server.get());
769 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
770 EXPECT_EQ(0, server->Listen(5));
771
772 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800773 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000774
jbauchf2a2bf42016-02-03 16:45:32 -0800775 // Accept connection which will be used for sending.
kwibergd0d81482017-04-18 03:18:22 -0700776 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700777 std::unique_ptr<AsyncSocket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800778 ASSERT_TRUE(sender);
779 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000780
781 // Both sides are now connected.
jbauchf2a2bf42016-02-03 16:45:32 -0800782 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700783 EXPECT_TRUE(sink.Check(receiver.get(), SSE_OPEN));
jbauchf2a2bf42016-02-03 16:45:32 -0800784 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
785 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
786
787 // Create test data.
788 rtc::Buffer send_buffer(0, data_size);
789 rtc::Buffer recv_buffer(0, data_size);
790 for (size_t i = 0; i < data_size; ++i) {
791 char ch = static_cast<char>(i % 256);
792 send_buffer.AppendData(&ch, sizeof(ch));
793 }
danilchapb7b9dca2016-08-05 05:55:43 -0700794 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000795
796 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800797 size_t sent_size = 0;
798 bool writable = true;
799 bool send_called = false;
800 bool readable = false;
801 bool recv_called = false;
802 while (recv_buffer.size() < send_buffer.size()) {
803 // Send as much as we can while we're cleared to send.
804 while (writable && sent_size < send_buffer.size()) {
805 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
806 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
807 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000808 // The first Send() after connecting or getting writability should
809 // succeed and send some data.
810 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800811 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000812 }
813 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800814 EXPECT_LE(sent, unsent_size);
815 sent_size += sent;
816 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 05:55:43 -0700817 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-03 16:45:32 -0800818 if (sent < unsent_size) {
819 // If max_send_size is limiting the amount to send per call such
820 // that the sent amount is less than the unsent amount, we simulate
821 // that the socket is no longer writable.
822 writable = false;
823 }
824 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000825 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800826 ASSERT_TRUE(sender->IsBlocking());
827 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000828 }
829 }
830
831 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800832 while (recv_buffer.size() < sent_size) {
833 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000834 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700835 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), SSE_READ), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800836 readable = true;
837 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000838 }
839
840 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 05:55:43 -0700841 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000842
jbauchf2a2bf42016-02-03 16:45:32 -0800843 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000844 // The first Recv() after getting readability should succeed and receive
845 // some data.
846 // TODO: The following line is disabled due to flakey pulse
847 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800848 // EXPECT_GT(recved_size, 0);
849 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000850 }
jbauchf2a2bf42016-02-03 16:45:32 -0800851 if (recved_size >= 0) {
852 EXPECT_LE(static_cast<size_t>(recved_size),
Yves Gerey665174f2018-06-19 15:03:05 +0200853 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 05:55:43 -0700854 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000855 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800856 ASSERT_TRUE(receiver->IsBlocking());
857 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000858 }
859 }
860
jbauchf2a2bf42016-02-03 16:45:32 -0800861 // Once all that we've sent has been received, expect to be able to send
862 // again.
863 if (!writable) {
kwibergd0d81482017-04-18 03:18:22 -0700864 ASSERT_TRUE_WAIT(sink.Check(sender.get(), SSE_WRITE), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800865 writable = true;
866 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000867 }
868 }
869
870 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800871 EXPECT_EQ(data_size, sent_size);
872 EXPECT_EQ(data_size, recv_buffer.size());
873 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000874
875 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800876 sender->Close();
877 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700878 EXPECT_TRUE(sink.Check(receiver.get(), SSE_CLOSE));
jbauchf2a2bf42016-02-03 16:45:32 -0800879 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000880}
881
882void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700883 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000884 SocketAddress accept_addr;
885
886 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700887 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000888 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
889 sink.Monitor(client.get());
890
891 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700892 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000893 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
894 sink.Monitor(server.get());
895 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
896 EXPECT_EQ(0, server->Listen(5));
897
898 // Attempt connection.
899 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
900
901 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700902 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700903 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000904 ASSERT_TRUE(accepted);
905 sink.Monitor(accepted.get());
906
907 // Both sides are now connected.
908 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700909 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000910 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
911 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
912
913 // Expect a writable callback from the connect.
kwibergd0d81482017-04-18 03:18:22 -0700914 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000915
916 // Fill the socket buffer.
917 char buf[1024 * 16] = {0};
918 int sends = 0;
Yves Gerey665174f2018-06-19 15:03:05 +0200919 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {
920 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000921 EXPECT_TRUE(accepted->IsBlocking());
922
923 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700924 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000925
926 // Pull data.
927 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200928 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000929 }
930
931 // Expect at least one additional writable callback.
kwibergd0d81482017-04-18 03:18:22 -0700932 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000933
934 // Adding data in response to the writeable callback shouldn't cause infinite
935 // callbacks.
936 int extras = 0;
937 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800938 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000939 rtc::Thread::Current()->ProcessMessages(1);
kwibergd0d81482017-04-18 03:18:22 -0700940 if (sink.Check(accepted.get(), SSE_WRITE)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000941 extras++;
942 }
943 }
944 EXPECT_LT(extras, 2);
945
946 // Close down.
947 accepted->Close();
948 client->Close();
949}
950
951void SocketTest::UdpInternal(const IPAddress& loopback) {
952 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
953 // Test basic bind and connect behavior.
Yves Gerey665174f2018-06-19 15:03:05 +0200954 AsyncSocket* socket = ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000955 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
956 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
957 SocketAddress addr1 = socket->GetLocalAddress();
958 EXPECT_EQ(0, socket->Connect(addr1));
959 EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
960 socket->Close();
961 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
962 delete socket;
963
964 // Test send/receive behavior.
jbauch555604a2016-04-26 03:13:22 -0700965 std::unique_ptr<TestClient> client1(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200966 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, addr1))));
jbauch555604a2016-04-26 03:13:22 -0700967 std::unique_ptr<TestClient> client2(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200968 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000969
970 SocketAddress addr2;
971 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
972 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
973
974 SocketAddress addr3;
975 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
976 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
977 EXPECT_EQ(addr3, addr1);
978 // TODO: figure out what the intent is here
979 for (int i = 0; i < 10; ++i) {
nisse32f25052017-05-08 01:57:18 -0700980 client2.reset(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200981 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000982
983 SocketAddress addr4;
984 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
985 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
986 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
987
988 SocketAddress addr5;
989 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
990 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
991 EXPECT_EQ(addr5, addr1);
992
993 addr2 = addr4;
994 }
995}
996
997void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
998 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
999 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
1000 // documentation.
1001 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
Yves Gerey665174f2018-06-19 15:03:05 +02001002 std::string dest =
1003 (loopback.family() == AF_INET6) ? "2001:db8::1" : "192.0.2.0";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001004 SocketAddress test_addr(dest, 2345);
1005
1006 // Test send
jbauch555604a2016-04-26 03:13:22 -07001007 std::unique_ptr<TestClient> client(
Karl Wiberg918f50c2018-07-05 11:40:33 +02001008 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001009 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -07001010 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001011 // Init the test packet just to avoid memcheck warning.
1012 memset(test_packet.get(), 0, test_packet_size);
1013 // Set the send buffer size to the same size as the test packet to have a
1014 // better chance to get EWOULDBLOCK.
1015 int send_buffer_size = test_packet_size;
1016#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
1017 send_buffer_size /= 2;
1018#endif
1019 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
1020
1021 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001022 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001023 int sent_packet_num = 0;
1024 int expected_error = EWOULDBLOCK;
1025 while (start_ms + kTimeout > Time()) {
1026 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
1027 ++sent_packet_num;
1028 if (ret != test_packet_size) {
1029 error = client->GetError();
1030 if (error == expected_error) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001031 RTC_LOG(LS_INFO) << "Got expected error code after sending "
1032 << sent_packet_num << " packets.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001033 break;
1034 }
1035 }
1036 }
1037 EXPECT_EQ(expected_error, error);
1038 EXPECT_FALSE(client->ready_to_send());
1039 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
Mirko Bonadei675513b2017-11-09 11:09:25 +01001040 RTC_LOG(LS_INFO) << "Got SignalReadyToSend";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001041}
1042
1043void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
jbauch555604a2016-04-26 03:13:22 -07001044 std::unique_ptr<AsyncSocket> socket(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001045 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
1046 socket->Bind(SocketAddress(loopback, 0));
1047
1048 // Check SNDBUF/RCVBUF.
1049 const int desired_size = 12345;
1050#if defined(WEBRTC_LINUX)
1051 // Yes, really. It's in the kernel source.
1052 const int expected_size = desired_size * 2;
1053#else // !WEBRTC_LINUX
1054 const int expected_size = desired_size;
1055#endif // !WEBRTC_LINUX
1056 int recv_size = 0;
1057 int send_size = 0;
1058 // get the initial sizes
1059 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1060 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1061 // set our desired sizes
1062 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
1063 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
1064 // get the sizes again
1065 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1066 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1067 // make sure they are right
1068 ASSERT_EQ(expected_size, recv_size);
1069 ASSERT_EQ(expected_size, send_size);
1070
1071 // Check that we can't set NODELAY on a UDP socket.
1072 int current_nd, desired_nd = 1;
1073 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1074 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -08001075
1076#if defined(WEBRTC_POSIX)
1077 // Check DSCP.
1078 int current_dscp, desired_dscp = 1;
1079 ASSERT_NE(-1, socket->GetOption(Socket::OPT_DSCP, &current_dscp));
1080 ASSERT_NE(-1, socket->SetOption(Socket::OPT_DSCP, desired_dscp));
1081 ASSERT_NE(-1, socket->GetOption(Socket::OPT_DSCP, &current_dscp));
1082 ASSERT_EQ(desired_dscp, current_dscp);
1083#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001084}
1085
Stefan Holmer9131efd2016-05-23 18:19:26 +02001086void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
1087 std::unique_ptr<Socket> socket(
1088 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
1089 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1090 SocketAddress address = socket->GetLocalAddress();
1091
nissedeb95f32016-11-28 01:54:54 -08001092 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001093 socket->SendTo("foo", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001094 int64_t recv_timestamp_1;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001095 char buffer[3];
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001096 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1);
1097 EXPECT_GT(recv_timestamp_1, -1);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001098
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001099 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001100 Thread::SleepMs(kTimeBetweenPacketsMs);
1101
nissedeb95f32016-11-28 01:54:54 -08001102 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001103 socket->SendTo("bar", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001104 int64_t recv_timestamp_2;
1105 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2);
1106
1107 int64_t system_time_diff = send_time_2 - send_time_1;
1108 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1109 // Compare against the system time at the point of sending, because
1110 // SleepMs may not sleep for exactly the requested time.
1111 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001112}
1113
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001114} // namespace rtc