blob: 80b28bb8faa6d3bc1cfc34f59fdba4f5a4749137 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:261/*
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 17:08:3311#include "rtc_base/socket.h"
12
Yves Gerey3e707812018-11-28 15:47:4913#include <errno.h>
14#include <stdint.h>
15#include <string.h>
Jonas Olssona4d87372019-07-05 17:08:3316
jbauch555604a2016-04-26 10:13:2217#include <memory>
18
Karl Wiberg918f50c2018-07-05 09:40:3319#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3120#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 17:11:0021#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 04:47:3124#include "rtc_base/buffer.h"
25#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 15:47:4926#include "rtc_base/location.h"
27#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 17:11:0028#include "rtc_base/message_handler.h"
Steve Anton10542f22019-01-11 17:11:0029#include "rtc_base/net_helpers.h"
Steve Anton10542f22019-01-11 17:11:0030#include "rtc_base/socket_address.h"
31#include "rtc_base/socket_server.h"
Yves Gerey3e707812018-11-28 15:47:4932#include "rtc_base/socket_unittest.h"
Steve Anton10542f22019-01-11 17:11:0033#include "rtc_base/test_client.h"
34#include "rtc_base/test_utils.h"
Yves Gerey3e707812018-11-28 15:47:4935#include "rtc_base/third_party/sigslot/sigslot.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3136#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 17:11:0037#include "rtc_base/time_utils.h"
henrike@webrtc.orgf0488722014-05-13 18:00:2638
39namespace rtc {
40
kwibergd0d81482017-04-18 10:18:2241using 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 10:09:2548#define MAYBE_SKIP_IPV6 \
49 if (!HasIPv6Enabled()) { \
50 RTC_LOG(LS_INFO) << "No IPv6... skipping"; \
51 return; \
henrike@webrtc.orgf0488722014-05-13 18:00:2652 }
53
Taylor Brandstetter2b3bf6b2016-05-19 21:57:3154// Data size to be used in TcpInternal tests.
55static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
henrike@webrtc.orgf0488722014-05-13 18:00:2656
Steve Anton9de3aac2017-10-24 17:08:2657void SocketTest::SetUp() {
58 ss_ = Thread::Current()->socketserver();
59}
60
henrike@webrtc.orgf0488722014-05-13 18:00:2661void 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 10:09:2576 RTC_LOG(LS_INFO) << "Skipping IPv6 DNS test";
henrike@webrtc.orgf0488722014-05-13 18:00:2677 // 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
152void SocketTest::TestSocketServerWaitIPv4() {
153 SocketServerWaitInternal(kIPv4Loopback);
154}
155
156void SocketTest::TestSocketServerWaitIPv6() {
157 MAYBE_SKIP_IPV6;
158 SocketServerWaitInternal(kIPv6Loopback);
159}
160
161void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-04 00:45:32162 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26163}
164
165void SocketTest::TestTcpIPv6() {
166 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-04 00:45:32167 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26168}
169
170void SocketTest::TestSingleFlowControlCallbackIPv4() {
171 SingleFlowControlCallbackInternal(kIPv4Loopback);
172}
173
174void SocketTest::TestSingleFlowControlCallbackIPv6() {
175 MAYBE_SKIP_IPV6;
176 SingleFlowControlCallbackInternal(kIPv6Loopback);
177}
178
179void SocketTest::TestUdpIPv4() {
180 UdpInternal(kIPv4Loopback);
181}
182
183void SocketTest::TestUdpIPv6() {
184 MAYBE_SKIP_IPV6;
185 UdpInternal(kIPv6Loopback);
186}
187
188void SocketTest::TestUdpReadyToSendIPv4() {
189#if !defined(WEBRTC_MAC)
190 // TODO(ronghuawu): Enable this test on mac/ios.
191 UdpReadyToSend(kIPv4Loopback);
192#endif
193}
194
195void SocketTest::TestUdpReadyToSendIPv6() {
196#if defined(WEBRTC_WIN)
197 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
198 MAYBE_SKIP_IPV6;
199 UdpReadyToSend(kIPv6Loopback);
200#endif
201}
202
203void SocketTest::TestGetSetOptionsIPv4() {
204 GetSetOptionsInternal(kIPv4Loopback);
205}
206
207void SocketTest::TestGetSetOptionsIPv6() {
208 MAYBE_SKIP_IPV6;
209 GetSetOptionsInternal(kIPv6Loopback);
210}
211
Taylor Brandstetter6f825352016-08-11 22:38:28212void SocketTest::TestSocketRecvTimestampIPv4() {
Stefan Holmer9131efd2016-05-23 16:19:26213 SocketRecvTimestamp(kIPv4Loopback);
214}
215
Taylor Brandstetter6f825352016-08-11 22:38:28216void SocketTest::TestSocketRecvTimestampIPv6() {
217 MAYBE_SKIP_IPV6;
218 SocketRecvTimestamp(kIPv6Loopback);
219}
220
henrike@webrtc.orgf0488722014-05-13 18:00:26221// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
222// values on Windows, but an empty address of the same family on Linux/MacOS X.
223bool IsUnspecOrEmptyIP(const IPAddress& address) {
224#if !defined(WEBRTC_WIN)
225 return IPIsAny(address);
226#else
227 return address.family() == AF_UNSPEC;
228#endif
229}
230
231void SocketTest::ConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 10:18:22232 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26233 SocketAddress accept_addr;
234
235 // Create client.
jbauch555604a2016-04-26 10:13:22236 std::unique_ptr<AsyncSocket> client(
237 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26238 sink.Monitor(client.get());
239 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
Jonas Olssonabbe8412018-04-03 11:40:05240 EXPECT_TRUE(IsUnspecOrEmptyIP(client->GetLocalAddress().ipaddr()));
henrike@webrtc.orgf0488722014-05-13 18:00:26241
242 // Create server and listen.
jbauch555604a2016-04-26 10:13:22243 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26244 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
245 sink.Monitor(server.get());
246 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
247 EXPECT_EQ(0, server->Listen(5));
248 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
249
250 // Ensure no pending server connections, since we haven't done anything yet.
kwibergd0d81482017-04-18 10:18:22251 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 22:06:41252 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26253 EXPECT_TRUE(accept_addr.IsNil());
254
255 // Attempt connect to listening socket.
256 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
257 EXPECT_FALSE(client->GetLocalAddress().IsNil());
258 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
259
260 // Client is connecting, outcome not yet determined.
261 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 10:18:22262 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
263 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26264
265 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 10:18:22266 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 10:13:22267 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26268 ASSERT_TRUE(accepted);
269 EXPECT_FALSE(accept_addr.IsNil());
270 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
271
272 // Connected from server perspective, check the addresses are correct.
273 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
274 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
275 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
276
277 // Connected from client perspective, check the addresses are correct.
278 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22279 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
280 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26281 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
282 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
283}
284
285void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
286 const std::string& host) {
kwibergd0d81482017-04-18 10:18:22287 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26288 SocketAddress accept_addr;
289
290 // Create client.
jbauch555604a2016-04-26 10:13:22291 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26292 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
293 sink.Monitor(client.get());
294
295 // Create server and listen.
jbauch555604a2016-04-26 10:13:22296 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26297 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
298 sink.Monitor(server.get());
299 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
300 EXPECT_EQ(0, server->Listen(5));
301
302 // Attempt connect to listening socket.
303 SocketAddress dns_addr(server->GetLocalAddress());
304 dns_addr.SetIP(host);
305 EXPECT_EQ(0, client->Connect(dns_addr));
306 // TODO: Bind when doing DNS lookup.
Yves Gerey665174f2018-06-19 13:03:05307 // EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
henrike@webrtc.orgf0488722014-05-13 18:00:26308
309 // Client is connecting, outcome not yet determined.
310 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 10:18:22311 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
312 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26313
314 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 10:18:22315 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 10:13:22316 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26317 ASSERT_TRUE(accepted);
318 EXPECT_FALSE(accept_addr.IsNil());
319 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
320
321 // Connected from server perspective, check the addresses are correct.
322 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
323 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
324 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
325
326 // Connected from client perspective, check the addresses are correct.
327 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22328 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
329 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26330 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
331 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
332}
333
334void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 10:18:22335 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26336 SocketAddress accept_addr;
337
338 // Create client.
jbauch555604a2016-04-26 10:13:22339 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26340 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
341 sink.Monitor(client.get());
342
343 // Create server, but don't listen yet.
jbauch555604a2016-04-26 10:13:22344 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26345 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
346 sink.Monitor(server.get());
347 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
348
349 // Attempt connect to a non-existent socket.
350 // We don't connect to the server socket created above, since on
351 // MacOS it takes about 75 seconds to get back an error!
352 SocketAddress bogus_addr(loopback, 65535);
353 EXPECT_EQ(0, client->Connect(bogus_addr));
354
355 // Wait for connection to fail (ECONNREFUSED).
356 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22357 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
358 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26359 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
360
361 // Should be no pending server connections.
kwibergd0d81482017-04-18 10:18:22362 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 22:06:41363 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26364 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
365}
366
367void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 10:18:22368 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26369 SocketAddress accept_addr;
370
371 // Create client.
jbauch555604a2016-04-26 10:13:22372 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26373 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
374 sink.Monitor(client.get());
375
376 // Create server, but don't listen yet.
jbauch555604a2016-04-26 10:13:22377 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26378 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
379 sink.Monitor(server.get());
380 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
381
382 // Attempt connect to a non-existent host.
383 // We don't connect to the server socket created above, since on
384 // MacOS it takes about 75 seconds to get back an error!
385 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
386 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
387
388 // Wait for connection to fail (EHOSTNOTFOUND).
389 bool dns_lookup_finished = false;
390 WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
391 dns_lookup_finished);
392 if (!dns_lookup_finished) {
Mirko Bonadei675513b2017-11-09 10:09:25393 RTC_LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
394 << "seconds.";
henrike@webrtc.orgf0488722014-05-13 18:00:26395 return;
396 }
397
398 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22399 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
400 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26401 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
402 // Should be no pending server connections.
kwibergd0d81482017-04-18 10:18:22403 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 22:06:41404 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26405 EXPECT_TRUE(accept_addr.IsNil());
406}
407
408void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
409 // Create server and listen.
jbauch555604a2016-04-26 10:13:22410 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26411 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
412 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
413 EXPECT_EQ(0, server->Listen(5));
414
415 // Create a client and put in to CS_CLOSED state.
jbauch555604a2016-04-26 10:13:22416 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26417 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
418 EXPECT_EQ(0, client->Close());
419 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
420
421 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
422 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
423 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
424}
425
426void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
427 // Create server and listen.
kwibergd0d81482017-04-18 10:18:22428 StreamSink sink;
jbauch555604a2016-04-26 10:13:22429 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26430 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
431 sink.Monitor(server.get());
432 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
433 EXPECT_EQ(0, server->Listen(5));
434 // Create client, connect.
jbauch555604a2016-04-26 10:13:22435 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26436 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
437 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
438 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
439 // Try to connect again. Should fail, but not interfere with original attempt.
440 EXPECT_EQ(SOCKET_ERROR,
441 client->Connect(SocketAddress(server->GetLocalAddress())));
442
443 // Accept the original connection.
444 SocketAddress accept_addr;
kwibergd0d81482017-04-18 10:18:22445 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 10:13:22446 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26447 ASSERT_TRUE(accepted);
448 EXPECT_FALSE(accept_addr.IsNil());
449
450 // Check the states and addresses.
451 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
452 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
453 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
454 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
455 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
456 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
457
458 // Try to connect again, to an unresolved hostname.
459 // Shouldn't break anything.
Yves Gerey665174f2018-06-19 13:03:05460 EXPECT_EQ(SOCKET_ERROR, client->Connect(SocketAddress(
461 "localhost", server->GetLocalAddress().port())));
henrike@webrtc.orgf0488722014-05-13 18:00:26462 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
463 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
464 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
465 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
466}
467
468void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 10:18:22469 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26470
471 // Create client.
jbauch555604a2016-04-26 10:13:22472 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26473 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
474 sink.Monitor(client.get());
475
476 // Create server and listen.
jbauch555604a2016-04-26 10:13:22477 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26478 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
479 sink.Monitor(server.get());
480 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
481 EXPECT_EQ(0, server->Listen(5));
482
483 // Attempt connect to listening socket.
484 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
485
486 // Close down the server while the socket is in the accept queue.
kwibergd0d81482017-04-18 10:18:22487 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26488 server->Close();
489
490 // This should fail the connection for the client. Clean up.
491 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22492 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26493 client->Close();
494}
495
496void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 10:18:22497 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26498 SocketAddress accept_addr;
499
500 // Create client.
jbauch555604a2016-04-26 10:13:22501 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26502 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
503 sink.Monitor(client.get());
504
505 // Create server and listen.
jbauch555604a2016-04-26 10:13:22506 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26507 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
508 sink.Monitor(server.get());
509 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
510 EXPECT_EQ(0, server->Listen(5));
511
512 // Attempt connect to listening socket.
513 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
514
515 // Close down the client while the socket is in the accept queue.
kwibergd0d81482017-04-18 10:18:22516 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26517 client->Close();
518
519 // The connection should still be able to be accepted.
jbauch555604a2016-04-26 10:13:22520 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26521 ASSERT_TRUE(accepted);
522 sink.Monitor(accepted.get());
523 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
524
525 // The accepted socket should then close (possibly with err, timing-related)
526 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22527 EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE) ||
528 sink.Check(accepted.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26529
530 // The client should not get a close event.
kwibergd0d81482017-04-18 10:18:22531 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26532}
533
534void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 10:18:22535 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26536 SocketAddress accept_addr;
537
538 // Create client.
jbauch555604a2016-04-26 10:13:22539 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26540 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
541 sink.Monitor(client.get());
542
543 // Create server and listen.
jbauch555604a2016-04-26 10:13:22544 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26545 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
546 sink.Monitor(server.get());
547 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
548 EXPECT_EQ(0, server->Listen(5));
549
550 // Attempt connection.
551 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
552
553 // Accept connection.
kwibergd0d81482017-04-18 10:18:22554 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 10:13:22555 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26556 ASSERT_TRUE(accepted);
557 sink.Monitor(accepted.get());
558
559 // Both sides are now connected.
560 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22561 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26562 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
563 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
564
565 // Send data to the client, and then close the connection.
566 EXPECT_EQ(1, accepted->Send("a", 1));
567 accepted->Close();
568 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
569
570 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 10:18:22571 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
572 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26573 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
574
575 // Ensure the data can be read.
576 char buffer[10];
Stefan Holmer9131efd2016-05-23 16:19:26577 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26578 EXPECT_EQ('a', buffer[0]);
579
580 // Now we should close, but the remote address will remain.
581 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22582 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26583 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
584
585 // The closer should not get a close signal.
kwibergd0d81482017-04-18 10:18:22586 EXPECT_FALSE(sink.Check(accepted.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26587 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
588
589 // And the closee should only get a single signal.
590 Thread::Current()->ProcessMessages(0);
kwibergd0d81482017-04-18 10:18:22591 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26592
593 // Close down the client and ensure all is good.
594 client->Close();
kwibergd0d81482017-04-18 10:18:22595 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26596 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
597}
598
599class SocketCloser : public sigslot::has_slots<> {
600 public:
601 void OnClose(AsyncSocket* socket, int error) {
602 socket->Close(); // Deleting here would blow up the vector of handlers
603 // for the socket's signal.
604 }
605};
606
607void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 10:18:22608 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26609 SocketCloser closer;
610 SocketAddress accept_addr;
611
612 // Create client.
jbauch555604a2016-04-26 10:13:22613 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26614 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
615 sink.Monitor(client.get());
616 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
617
618 // Create server and listen.
jbauch555604a2016-04-26 10:13:22619 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26620 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
621 sink.Monitor(server.get());
622 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
623 EXPECT_EQ(0, server->Listen(5));
624
625 // Attempt connection.
626 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
627
628 // Accept connection.
kwibergd0d81482017-04-18 10:18:22629 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 10:13:22630 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26631 ASSERT_TRUE(accepted);
632 sink.Monitor(accepted.get());
633
634 // Both sides are now connected.
635 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22636 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26637 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
638 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
639
640 // Send data to the client, and then close the connection.
641 accepted->Close();
642 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
643
644 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 10:18:22645 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26646 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
647
648 // Now we should be closed and invalidated
649 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22650 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26651 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
652}
653
654class Sleeper : public MessageHandler {
655 public:
Steve Anton9de3aac2017-10-24 17:08:26656 void OnMessage(Message* msg) override { Thread::Current()->SleepMs(500); }
henrike@webrtc.orgf0488722014-05-13 18:00:26657};
658
659void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 10:18:22660 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26661 SocketAddress accept_addr;
662
663 // Create & connect server and client sockets.
jbauch555604a2016-04-26 10:13:22664 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26665 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauch555604a2016-04-26 10:13:22666 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26667 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
668 sink.Monitor(client.get());
669 sink.Monitor(server.get());
670 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
671 EXPECT_EQ(0, server->Listen(5));
672
673 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
kwibergd0d81482017-04-18 10:18:22674 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26675
jbauch555604a2016-04-26 10:13:22676 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26677 ASSERT_TRUE(accepted);
678 sink.Monitor(accepted.get());
679 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
680 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
681 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
682
683 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22684 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
685 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26686 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
687 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
688
689 // Do an i/o operation, triggering an eventual callback.
kwibergd0d81482017-04-18 10:18:22690 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26691 char buf[1024] = {0};
692
693 EXPECT_EQ(1024, client->Send(buf, 1024));
kwibergd0d81482017-04-18 10:18:22694 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26695
696 // Shouldn't signal when blocked in a thread Send, where process_io is false.
tommie7251592017-07-14 21:44:46697 std::unique_ptr<Thread> thread(Thread::CreateWithSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26698 thread->Start();
699 Sleeper sleeper;
700 TypedMessageData<AsyncSocket*> data(client.get());
Taylor Brandstetter5d97a9a2016-06-10 21:17:27701 thread->Send(RTC_FROM_HERE, &sleeper, 0, &data);
kwibergd0d81482017-04-18 10:18:22702 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26703
704 // But should signal when process_io is true.
kwibergd0d81482017-04-18 10:18:22705 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 16:19:26706 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26707}
708
Yves Gerey665174f2018-06-19 13:03:05709void SocketTest::TcpInternal(const IPAddress& loopback,
710 size_t data_size,
711 ptrdiff_t max_send_size) {
kwibergd0d81482017-04-18 10:18:22712 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26713 SocketAddress accept_addr;
714
jbauchf2a2bf42016-02-04 00:45:32715 // Create receiving client.
jbauch555604a2016-04-26 10:13:22716 std::unique_ptr<AsyncSocket> receiver(
henrike@webrtc.orgf0488722014-05-13 18:00:26717 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-04 00:45:32718 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26719
720 // Create server and listen.
jbauch555604a2016-04-26 10:13:22721 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26722 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
723 sink.Monitor(server.get());
724 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
725 EXPECT_EQ(0, server->Listen(5));
726
727 // Attempt connection.
jbauchf2a2bf42016-02-04 00:45:32728 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26729
jbauchf2a2bf42016-02-04 00:45:32730 // Accept connection which will be used for sending.
kwibergd0d81482017-04-18 10:18:22731 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 10:13:22732 std::unique_ptr<AsyncSocket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-04 00:45:32733 ASSERT_TRUE(sender);
734 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26735
736 // Both sides are now connected.
jbauchf2a2bf42016-02-04 00:45:32737 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22738 EXPECT_TRUE(sink.Check(receiver.get(), SSE_OPEN));
jbauchf2a2bf42016-02-04 00:45:32739 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
740 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
741
742 // Create test data.
743 rtc::Buffer send_buffer(0, data_size);
744 rtc::Buffer recv_buffer(0, data_size);
745 for (size_t i = 0; i < data_size; ++i) {
746 char ch = static_cast<char>(i % 256);
747 send_buffer.AppendData(&ch, sizeof(ch));
748 }
danilchapb7b9dca2016-08-05 12:55:43749 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26750
751 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-04 00:45:32752 size_t sent_size = 0;
753 bool writable = true;
754 bool send_called = false;
755 bool readable = false;
756 bool recv_called = false;
757 while (recv_buffer.size() < send_buffer.size()) {
758 // Send as much as we can while we're cleared to send.
759 while (writable && sent_size < send_buffer.size()) {
760 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
761 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
762 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26763 // The first Send() after connecting or getting writability should
764 // succeed and send some data.
765 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-04 00:45:32766 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26767 }
768 if (sent >= 0) {
jbauchf2a2bf42016-02-04 00:45:32769 EXPECT_LE(sent, unsent_size);
770 sent_size += sent;
771 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 12:55:43772 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-04 00:45:32773 if (sent < unsent_size) {
774 // If max_send_size is limiting the amount to send per call such
775 // that the sent amount is less than the unsent amount, we simulate
776 // that the socket is no longer writable.
777 writable = false;
778 }
779 }
henrike@webrtc.orgf0488722014-05-13 18:00:26780 } else {
jbauchf2a2bf42016-02-04 00:45:32781 ASSERT_TRUE(sender->IsBlocking());
782 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26783 }
784 }
785
786 // Read all the sent data.
jbauchf2a2bf42016-02-04 00:45:32787 while (recv_buffer.size() < sent_size) {
788 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26789 // Wait until data is available.
kwibergd0d81482017-04-18 10:18:22790 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), SSE_READ), kTimeout);
jbauchf2a2bf42016-02-04 00:45:32791 readable = true;
792 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26793 }
794
795 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 12:55:43796 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26797
jbauchf2a2bf42016-02-04 00:45:32798 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26799 // The first Recv() after getting readability should succeed and receive
800 // some data.
801 // TODO: The following line is disabled due to flakey pulse
802 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-04 00:45:32803 // EXPECT_GT(recved_size, 0);
804 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26805 }
jbauchf2a2bf42016-02-04 00:45:32806 if (recved_size >= 0) {
807 EXPECT_LE(static_cast<size_t>(recved_size),
Yves Gerey665174f2018-06-19 13:03:05808 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 12:55:43809 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26810 } else {
jbauchf2a2bf42016-02-04 00:45:32811 ASSERT_TRUE(receiver->IsBlocking());
812 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26813 }
814 }
815
jbauchf2a2bf42016-02-04 00:45:32816 // Once all that we've sent has been received, expect to be able to send
817 // again.
818 if (!writable) {
kwibergd0d81482017-04-18 10:18:22819 ASSERT_TRUE_WAIT(sink.Check(sender.get(), SSE_WRITE), kTimeout);
jbauchf2a2bf42016-02-04 00:45:32820 writable = true;
821 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26822 }
823 }
824
825 // The received data matches the sent data.
jbauchf2a2bf42016-02-04 00:45:32826 EXPECT_EQ(data_size, sent_size);
827 EXPECT_EQ(data_size, recv_buffer.size());
828 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26829
830 // Close down.
jbauchf2a2bf42016-02-04 00:45:32831 sender->Close();
832 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22833 EXPECT_TRUE(sink.Check(receiver.get(), SSE_CLOSE));
jbauchf2a2bf42016-02-04 00:45:32834 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26835}
836
837void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 10:18:22838 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26839 SocketAddress accept_addr;
840
841 // Create client.
jbauch555604a2016-04-26 10:13:22842 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26843 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
844 sink.Monitor(client.get());
845
846 // Create server and listen.
jbauch555604a2016-04-26 10:13:22847 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26848 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
849 sink.Monitor(server.get());
850 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
851 EXPECT_EQ(0, server->Listen(5));
852
853 // Attempt connection.
854 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
855
856 // Accept connection.
kwibergd0d81482017-04-18 10:18:22857 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 10:13:22858 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26859 ASSERT_TRUE(accepted);
860 sink.Monitor(accepted.get());
861
862 // Both sides are now connected.
863 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 10:18:22864 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26865 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
866 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
867
868 // Expect a writable callback from the connect.
kwibergd0d81482017-04-18 10:18:22869 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26870
871 // Fill the socket buffer.
872 char buf[1024 * 16] = {0};
873 int sends = 0;
Yves Gerey665174f2018-06-19 13:03:05874 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {
875 }
henrike@webrtc.orgf0488722014-05-13 18:00:26876 EXPECT_TRUE(accepted->IsBlocking());
877
878 // Wait until data is available.
kwibergd0d81482017-04-18 10:18:22879 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26880
881 // Pull data.
882 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 16:19:26883 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26884 }
885
886 // Expect at least one additional writable callback.
kwibergd0d81482017-04-18 10:18:22887 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26888
889 // Adding data in response to the writeable callback shouldn't cause infinite
890 // callbacks.
891 int extras = 0;
892 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-11 07:44:30893 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26894 rtc::Thread::Current()->ProcessMessages(1);
kwibergd0d81482017-04-18 10:18:22895 if (sink.Check(accepted.get(), SSE_WRITE)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26896 extras++;
897 }
898 }
899 EXPECT_LT(extras, 2);
900
901 // Close down.
902 accepted->Close();
903 client->Close();
904}
905
906void SocketTest::UdpInternal(const IPAddress& loopback) {
907 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
908 // Test basic bind and connect behavior.
Yves Gerey665174f2018-06-19 13:03:05909 AsyncSocket* socket = ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
henrike@webrtc.orgf0488722014-05-13 18:00:26910 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
911 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
912 SocketAddress addr1 = socket->GetLocalAddress();
913 EXPECT_EQ(0, socket->Connect(addr1));
914 EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
915 socket->Close();
916 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
917 delete socket;
918
919 // Test send/receive behavior.
jbauch555604a2016-04-26 10:13:22920 std::unique_ptr<TestClient> client1(
Karl Wiberg918f50c2018-07-05 09:40:33921 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, addr1))));
jbauch555604a2016-04-26 10:13:22922 std::unique_ptr<TestClient> client2(
Karl Wiberg918f50c2018-07-05 09:40:33923 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26924
925 SocketAddress addr2;
926 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
927 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
928
929 SocketAddress addr3;
930 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
931 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
932 EXPECT_EQ(addr3, addr1);
933 // TODO: figure out what the intent is here
934 for (int i = 0; i < 10; ++i) {
nisse32f25052017-05-08 08:57:18935 client2.reset(
Karl Wiberg918f50c2018-07-05 09:40:33936 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26937
938 SocketAddress addr4;
939 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
940 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
941 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
942
943 SocketAddress addr5;
944 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
945 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
946 EXPECT_EQ(addr5, addr1);
947
948 addr2 = addr4;
949 }
950}
951
952void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
953 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
954 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
955 // documentation.
956 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
Yves Gerey665174f2018-06-19 13:03:05957 std::string dest =
958 (loopback.family() == AF_INET6) ? "2001:db8::1" : "192.0.2.0";
henrike@webrtc.orgf0488722014-05-13 18:00:26959 SocketAddress test_addr(dest, 2345);
960
961 // Test send
jbauch555604a2016-04-26 10:13:22962 std::unique_ptr<TestClient> client(
Karl Wiberg918f50c2018-07-05 09:40:33963 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26964 int test_packet_size = 1200;
jbauch555604a2016-04-26 10:13:22965 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26966 // Init the test packet just to avoid memcheck warning.
967 memset(test_packet.get(), 0, test_packet_size);
968 // Set the send buffer size to the same size as the test packet to have a
969 // better chance to get EWOULDBLOCK.
970 int send_buffer_size = test_packet_size;
971#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
972 send_buffer_size /= 2;
973#endif
974 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
975
976 int error = 0;
Peter Boström0c4e06b2015-10-07 10:23:21977 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26978 int sent_packet_num = 0;
979 int expected_error = EWOULDBLOCK;
980 while (start_ms + kTimeout > Time()) {
981 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
982 ++sent_packet_num;
983 if (ret != test_packet_size) {
984 error = client->GetError();
985 if (error == expected_error) {
Mirko Bonadei675513b2017-11-09 10:09:25986 RTC_LOG(LS_INFO) << "Got expected error code after sending "
987 << sent_packet_num << " packets.";
henrike@webrtc.orgf0488722014-05-13 18:00:26988 break;
989 }
990 }
991 }
992 EXPECT_EQ(expected_error, error);
993 EXPECT_FALSE(client->ready_to_send());
994 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
Mirko Bonadei675513b2017-11-09 10:09:25995 RTC_LOG(LS_INFO) << "Got SignalReadyToSend";
henrike@webrtc.orgf0488722014-05-13 18:00:26996}
997
998void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
jbauch555604a2016-04-26 10:13:22999 std::unique_ptr<AsyncSocket> socket(
henrike@webrtc.orgf0488722014-05-13 18:00:261000 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
1001 socket->Bind(SocketAddress(loopback, 0));
1002
1003 // Check SNDBUF/RCVBUF.
1004 const int desired_size = 12345;
1005#if defined(WEBRTC_LINUX)
1006 // Yes, really. It's in the kernel source.
1007 const int expected_size = desired_size * 2;
1008#else // !WEBRTC_LINUX
1009 const int expected_size = desired_size;
1010#endif // !WEBRTC_LINUX
1011 int recv_size = 0;
1012 int send_size = 0;
1013 // get the initial sizes
1014 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1015 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1016 // set our desired sizes
1017 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
1018 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
1019 // get the sizes again
1020 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1021 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1022 // make sure they are right
1023 ASSERT_EQ(expected_size, recv_size);
1024 ASSERT_EQ(expected_size, send_size);
1025
1026 // Check that we can't set NODELAY on a UDP socket.
1027 int current_nd, desired_nd = 1;
1028 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1029 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
henrike@webrtc.orgf0488722014-05-13 18:00:261030}
1031
Stefan Holmer9131efd2016-05-23 16:19:261032void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
1033 std::unique_ptr<Socket> socket(
1034 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
1035 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1036 SocketAddress address = socket->GetLocalAddress();
1037
nissedeb95f32016-11-28 09:54:541038 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 16:19:261039 socket->SendTo("foo", 3, address);
Taylor Brandstetter6f825352016-08-11 22:38:281040 int64_t recv_timestamp_1;
Stefan Holmer9131efd2016-05-23 16:19:261041 char buffer[3];
Taylor Brandstetter6f825352016-08-11 22:38:281042 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1);
1043 EXPECT_GT(recv_timestamp_1, -1);
Stefan Holmer9131efd2016-05-23 16:19:261044
Taylor Brandstetter6f825352016-08-11 22:38:281045 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 16:19:261046 Thread::SleepMs(kTimeBetweenPacketsMs);
1047
nissedeb95f32016-11-28 09:54:541048 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 16:19:261049 socket->SendTo("bar", 3, address);
Taylor Brandstetter6f825352016-08-11 22:38:281050 int64_t recv_timestamp_2;
1051 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2);
1052
1053 int64_t system_time_diff = send_time_2 - send_time_1;
1054 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1055 // Compare against the system time at the point of sending, because
1056 // SleepMs may not sleep for exactly the requested time.
1057 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 16:19:261058}
1059
henrike@webrtc.orgf0488722014-05-13 18:00:261060} // namespace rtc