blob: 3166ec7e612f91c7e10c1d9c2c259899a715e652 [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
Yves Gerey3e707812018-11-28 16:47:49 +010011#include <errno.h>
12#include <stdint.h>
13#include <string.h>
jbauch555604a2016-04-26 03:13:22 -070014#include <memory>
15
Karl Wiberg918f50c2018-07-05 11:40:33 +020016#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "rtc_base/async_packet_socket.h"
19#include "rtc_base/async_socket.h"
20#include "rtc_base/async_udp_socket.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/buffer.h"
22#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 16:47:49 +010023#include "rtc_base/location.h"
24#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "rtc_base/message_handler.h"
26#include "rtc_base/message_queue.h"
27#include "rtc_base/net_helpers.h"
Yves Gerey3e707812018-11-28 16:47:49 +010028#include "rtc_base/socket.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "rtc_base/socket_address.h"
30#include "rtc_base/socket_server.h"
Yves Gerey3e707812018-11-28 16:47:49 +010031#include "rtc_base/socket_unittest.h"
Steve Anton10542f22019-01-11 09:11:00 -080032#include "rtc_base/test_client.h"
33#include "rtc_base/test_utils.h"
Yves Gerey3e707812018-11-28 16:47:49 +010034#include "rtc_base/third_party/sigslot/sigslot.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020035#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080036#include "rtc_base/time_utils.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000037
38namespace rtc {
39
kwibergd0d81482017-04-18 03:18:22 -070040using webrtc::testing::SSE_CLOSE;
41using webrtc::testing::SSE_ERROR;
42using webrtc::testing::SSE_OPEN;
43using webrtc::testing::SSE_READ;
44using webrtc::testing::SSE_WRITE;
45using webrtc::testing::StreamSink;
46
Mirko Bonadei675513b2017-11-09 11:09:25 +010047#define MAYBE_SKIP_IPV6 \
48 if (!HasIPv6Enabled()) { \
49 RTC_LOG(LS_INFO) << "No IPv6... skipping"; \
50 return; \
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000051 }
52
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070053// Data size to be used in TcpInternal tests.
54static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000055
Steve Anton9de3aac2017-10-24 10:08:26 -070056void SocketTest::SetUp() {
57 ss_ = Thread::Current()->socketserver();
58}
59
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000060void SocketTest::TestConnectIPv4() {
61 ConnectInternal(kIPv4Loopback);
62}
63
64void SocketTest::TestConnectIPv6() {
65 MAYBE_SKIP_IPV6;
66 ConnectInternal(kIPv6Loopback);
67}
68
69void SocketTest::TestConnectWithDnsLookupIPv4() {
70 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
71}
72
73void SocketTest::TestConnectWithDnsLookupIPv6() {
74 // TODO: Enable this when DNS resolution supports IPv6.
Mirko Bonadei675513b2017-11-09 11:09:25 +010075 RTC_LOG(LS_INFO) << "Skipping IPv6 DNS test";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000076 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
77}
78
79void SocketTest::TestConnectFailIPv4() {
80 ConnectFailInternal(kIPv4Loopback);
81}
82
83void SocketTest::TestConnectFailIPv6() {
84 MAYBE_SKIP_IPV6;
85 ConnectFailInternal(kIPv6Loopback);
86}
87
88void SocketTest::TestConnectWithDnsLookupFailIPv4() {
89 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
90}
91
92void SocketTest::TestConnectWithDnsLookupFailIPv6() {
93 MAYBE_SKIP_IPV6;
94 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
95}
96
97void SocketTest::TestConnectWithClosedSocketIPv4() {
98 ConnectWithClosedSocketInternal(kIPv4Loopback);
99}
100
101void SocketTest::TestConnectWithClosedSocketIPv6() {
102 MAYBE_SKIP_IPV6;
103 ConnectWithClosedSocketInternal(kIPv6Loopback);
104}
105
106void SocketTest::TestConnectWhileNotClosedIPv4() {
107 ConnectWhileNotClosedInternal(kIPv4Loopback);
108}
109
110void SocketTest::TestConnectWhileNotClosedIPv6() {
111 MAYBE_SKIP_IPV6;
112 ConnectWhileNotClosedInternal(kIPv6Loopback);
113}
114
115void SocketTest::TestServerCloseDuringConnectIPv4() {
116 ServerCloseDuringConnectInternal(kIPv4Loopback);
117}
118
119void SocketTest::TestServerCloseDuringConnectIPv6() {
120 MAYBE_SKIP_IPV6;
121 ServerCloseDuringConnectInternal(kIPv6Loopback);
122}
123
124void SocketTest::TestClientCloseDuringConnectIPv4() {
125 ClientCloseDuringConnectInternal(kIPv4Loopback);
126}
127
128void SocketTest::TestClientCloseDuringConnectIPv6() {
129 MAYBE_SKIP_IPV6;
130 ClientCloseDuringConnectInternal(kIPv6Loopback);
131}
132
133void SocketTest::TestServerCloseIPv4() {
134 ServerCloseInternal(kIPv4Loopback);
135}
136
137void SocketTest::TestServerCloseIPv6() {
138 MAYBE_SKIP_IPV6;
139 ServerCloseInternal(kIPv6Loopback);
140}
141
142void SocketTest::TestCloseInClosedCallbackIPv4() {
143 CloseInClosedCallbackInternal(kIPv4Loopback);
144}
145
146void SocketTest::TestCloseInClosedCallbackIPv6() {
147 MAYBE_SKIP_IPV6;
148 CloseInClosedCallbackInternal(kIPv6Loopback);
149}
150
151void SocketTest::TestSocketServerWaitIPv4() {
152 SocketServerWaitInternal(kIPv4Loopback);
153}
154
155void SocketTest::TestSocketServerWaitIPv6() {
156 MAYBE_SKIP_IPV6;
157 SocketServerWaitInternal(kIPv6Loopback);
158}
159
160void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800161 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000162}
163
164void SocketTest::TestTcpIPv6() {
165 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800166 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000167}
168
169void SocketTest::TestSingleFlowControlCallbackIPv4() {
170 SingleFlowControlCallbackInternal(kIPv4Loopback);
171}
172
173void SocketTest::TestSingleFlowControlCallbackIPv6() {
174 MAYBE_SKIP_IPV6;
175 SingleFlowControlCallbackInternal(kIPv6Loopback);
176}
177
178void SocketTest::TestUdpIPv4() {
179 UdpInternal(kIPv4Loopback);
180}
181
182void SocketTest::TestUdpIPv6() {
183 MAYBE_SKIP_IPV6;
184 UdpInternal(kIPv6Loopback);
185}
186
187void SocketTest::TestUdpReadyToSendIPv4() {
188#if !defined(WEBRTC_MAC)
189 // TODO(ronghuawu): Enable this test on mac/ios.
190 UdpReadyToSend(kIPv4Loopback);
191#endif
192}
193
194void SocketTest::TestUdpReadyToSendIPv6() {
195#if defined(WEBRTC_WIN)
196 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
197 MAYBE_SKIP_IPV6;
198 UdpReadyToSend(kIPv6Loopback);
199#endif
200}
201
202void SocketTest::TestGetSetOptionsIPv4() {
203 GetSetOptionsInternal(kIPv4Loopback);
204}
205
206void SocketTest::TestGetSetOptionsIPv6() {
207 MAYBE_SKIP_IPV6;
208 GetSetOptionsInternal(kIPv6Loopback);
209}
210
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700211void SocketTest::TestSocketRecvTimestampIPv4() {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200212 SocketRecvTimestamp(kIPv4Loopback);
213}
214
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700215void SocketTest::TestSocketRecvTimestampIPv6() {
216 MAYBE_SKIP_IPV6;
217 SocketRecvTimestamp(kIPv6Loopback);
218}
219
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000220// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
221// values on Windows, but an empty address of the same family on Linux/MacOS X.
222bool IsUnspecOrEmptyIP(const IPAddress& address) {
223#if !defined(WEBRTC_WIN)
224 return IPIsAny(address);
225#else
226 return address.family() == AF_UNSPEC;
227#endif
228}
229
230void SocketTest::ConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700231 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000232 SocketAddress accept_addr;
233
234 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700235 std::unique_ptr<AsyncSocket> client(
236 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000237 sink.Monitor(client.get());
238 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
Jonas Olssonabbe8412018-04-03 13:40:05 +0200239 EXPECT_TRUE(IsUnspecOrEmptyIP(client->GetLocalAddress().ipaddr()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000240
241 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700242 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000243 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
244 sink.Monitor(server.get());
245 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
246 EXPECT_EQ(0, server->Listen(5));
247 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
248
249 // Ensure no pending server connections, since we haven't done anything yet.
kwibergd0d81482017-04-18 03:18:22 -0700250 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800251 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000252 EXPECT_TRUE(accept_addr.IsNil());
253
254 // Attempt connect to listening socket.
255 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
256 EXPECT_FALSE(client->GetLocalAddress().IsNil());
257 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
258
259 // Client is connecting, outcome not yet determined.
260 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700261 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
262 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000263
264 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700265 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700266 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000267 ASSERT_TRUE(accepted);
268 EXPECT_FALSE(accept_addr.IsNil());
269 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
270
271 // Connected from server perspective, check the addresses are correct.
272 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
273 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
274 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
275
276 // Connected from client perspective, check the addresses are correct.
277 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700278 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
279 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000280 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
281 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
282}
283
284void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
285 const std::string& host) {
kwibergd0d81482017-04-18 03:18:22 -0700286 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000287 SocketAddress accept_addr;
288
289 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700290 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000291 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
292 sink.Monitor(client.get());
293
294 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700295 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000296 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
297 sink.Monitor(server.get());
298 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
299 EXPECT_EQ(0, server->Listen(5));
300
301 // Attempt connect to listening socket.
302 SocketAddress dns_addr(server->GetLocalAddress());
303 dns_addr.SetIP(host);
304 EXPECT_EQ(0, client->Connect(dns_addr));
305 // TODO: Bind when doing DNS lookup.
Yves Gerey665174f2018-06-19 15:03:05 +0200306 // EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000307
308 // Client is connecting, outcome not yet determined.
309 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700310 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
311 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000312
313 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700314 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700315 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000316 ASSERT_TRUE(accepted);
317 EXPECT_FALSE(accept_addr.IsNil());
318 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
319
320 // Connected from server perspective, check the addresses are correct.
321 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
322 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
323 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
324
325 // Connected from client perspective, check the addresses are correct.
326 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700327 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
328 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000329 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
330 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
331}
332
333void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700334 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000335 SocketAddress accept_addr;
336
337 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700338 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000339 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
340 sink.Monitor(client.get());
341
342 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700343 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000344 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
345 sink.Monitor(server.get());
346 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
347
348 // Attempt connect to a non-existent socket.
349 // We don't connect to the server socket created above, since on
350 // MacOS it takes about 75 seconds to get back an error!
351 SocketAddress bogus_addr(loopback, 65535);
352 EXPECT_EQ(0, client->Connect(bogus_addr));
353
354 // Wait for connection to fail (ECONNREFUSED).
355 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700356 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
357 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000358 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
359
360 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700361 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800362 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000363 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
364}
365
366void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700367 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000368 SocketAddress accept_addr;
369
370 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700371 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000372 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
373 sink.Monitor(client.get());
374
375 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700376 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000377 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
378 sink.Monitor(server.get());
379 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
380
381 // Attempt connect to a non-existent host.
382 // We don't connect to the server socket created above, since on
383 // MacOS it takes about 75 seconds to get back an error!
384 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
385 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
386
387 // Wait for connection to fail (EHOSTNOTFOUND).
388 bool dns_lookup_finished = false;
389 WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
390 dns_lookup_finished);
391 if (!dns_lookup_finished) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100392 RTC_LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
393 << "seconds.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000394 return;
395 }
396
397 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700398 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
399 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000400 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
401 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700402 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800403 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000404 EXPECT_TRUE(accept_addr.IsNil());
405}
406
407void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
408 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700409 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000410 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
411 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
412 EXPECT_EQ(0, server->Listen(5));
413
414 // Create a client and put in to CS_CLOSED state.
jbauch555604a2016-04-26 03:13:22 -0700415 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000416 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
417 EXPECT_EQ(0, client->Close());
418 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
419
420 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
421 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
422 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
423}
424
425void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
426 // Create server and listen.
kwibergd0d81482017-04-18 03:18:22 -0700427 StreamSink sink;
jbauch555604a2016-04-26 03:13:22 -0700428 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000429 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
430 sink.Monitor(server.get());
431 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
432 EXPECT_EQ(0, server->Listen(5));
433 // Create client, connect.
jbauch555604a2016-04-26 03:13:22 -0700434 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000435 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
436 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
437 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
438 // Try to connect again. Should fail, but not interfere with original attempt.
439 EXPECT_EQ(SOCKET_ERROR,
440 client->Connect(SocketAddress(server->GetLocalAddress())));
441
442 // Accept the original connection.
443 SocketAddress accept_addr;
kwibergd0d81482017-04-18 03:18:22 -0700444 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700445 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000446 ASSERT_TRUE(accepted);
447 EXPECT_FALSE(accept_addr.IsNil());
448
449 // Check the states and addresses.
450 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
451 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
452 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
453 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
454 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
455 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
456
457 // Try to connect again, to an unresolved hostname.
458 // Shouldn't break anything.
Yves Gerey665174f2018-06-19 15:03:05 +0200459 EXPECT_EQ(SOCKET_ERROR, client->Connect(SocketAddress(
460 "localhost", server->GetLocalAddress().port())));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000461 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
462 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
463 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
464 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
465}
466
467void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700468 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000469
470 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700471 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000472 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
473 sink.Monitor(client.get());
474
475 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700476 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000477 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
478 sink.Monitor(server.get());
479 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
480 EXPECT_EQ(0, server->Listen(5));
481
482 // Attempt connect to listening socket.
483 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
484
485 // Close down the server while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700486 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000487 server->Close();
488
489 // This should fail the connection for the client. Clean up.
490 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700491 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000492 client->Close();
493}
494
495void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700496 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000497 SocketAddress accept_addr;
498
499 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700500 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000501 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
502 sink.Monitor(client.get());
503
504 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700505 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000506 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
507 sink.Monitor(server.get());
508 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
509 EXPECT_EQ(0, server->Listen(5));
510
511 // Attempt connect to listening socket.
512 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
513
514 // Close down the client while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700515 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000516 client->Close();
517
518 // The connection should still be able to be accepted.
jbauch555604a2016-04-26 03:13:22 -0700519 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000520 ASSERT_TRUE(accepted);
521 sink.Monitor(accepted.get());
522 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
523
524 // The accepted socket should then close (possibly with err, timing-related)
525 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700526 EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE) ||
527 sink.Check(accepted.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000528
529 // The client should not get a close event.
kwibergd0d81482017-04-18 03:18:22 -0700530 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000531}
532
533void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700534 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000535 SocketAddress accept_addr;
536
537 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700538 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000539 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
540 sink.Monitor(client.get());
541
542 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700543 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000544 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
545 sink.Monitor(server.get());
546 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
547 EXPECT_EQ(0, server->Listen(5));
548
549 // Attempt connection.
550 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
551
552 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700553 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700554 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000555 ASSERT_TRUE(accepted);
556 sink.Monitor(accepted.get());
557
558 // Both sides are now connected.
559 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700560 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000561 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
562 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
563
564 // Send data to the client, and then close the connection.
565 EXPECT_EQ(1, accepted->Send("a", 1));
566 accepted->Close();
567 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
568
569 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700570 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
571 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000572 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
573
574 // Ensure the data can be read.
575 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200576 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000577 EXPECT_EQ('a', buffer[0]);
578
579 // Now we should close, but the remote address will remain.
580 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700581 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000582 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
583
584 // The closer should not get a close signal.
kwibergd0d81482017-04-18 03:18:22 -0700585 EXPECT_FALSE(sink.Check(accepted.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000586 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
587
588 // And the closee should only get a single signal.
589 Thread::Current()->ProcessMessages(0);
kwibergd0d81482017-04-18 03:18:22 -0700590 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000591
592 // Close down the client and ensure all is good.
593 client->Close();
kwibergd0d81482017-04-18 03:18:22 -0700594 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000595 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
596}
597
598class SocketCloser : public sigslot::has_slots<> {
599 public:
600 void OnClose(AsyncSocket* socket, int error) {
601 socket->Close(); // Deleting here would blow up the vector of handlers
602 // for the socket's signal.
603 }
604};
605
606void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700607 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000608 SocketCloser closer;
609 SocketAddress accept_addr;
610
611 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700612 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000613 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
614 sink.Monitor(client.get());
615 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
616
617 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700618 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000619 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
620 sink.Monitor(server.get());
621 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
622 EXPECT_EQ(0, server->Listen(5));
623
624 // Attempt connection.
625 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
626
627 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700628 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700629 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000630 ASSERT_TRUE(accepted);
631 sink.Monitor(accepted.get());
632
633 // Both sides are now connected.
634 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700635 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000636 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
637 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
638
639 // Send data to the client, and then close the connection.
640 accepted->Close();
641 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
642
643 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700644 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000645 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
646
647 // Now we should be closed and invalidated
648 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700649 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000650 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
651}
652
653class Sleeper : public MessageHandler {
654 public:
Steve Anton9de3aac2017-10-24 10:08:26 -0700655 void OnMessage(Message* msg) override { Thread::Current()->SleepMs(500); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000656};
657
658void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700659 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000660 SocketAddress accept_addr;
661
662 // Create & connect server and client sockets.
jbauch555604a2016-04-26 03:13:22 -0700663 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000664 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauch555604a2016-04-26 03:13:22 -0700665 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000666 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
667 sink.Monitor(client.get());
668 sink.Monitor(server.get());
669 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
670 EXPECT_EQ(0, server->Listen(5));
671
672 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
kwibergd0d81482017-04-18 03:18:22 -0700673 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000674
jbauch555604a2016-04-26 03:13:22 -0700675 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000676 ASSERT_TRUE(accepted);
677 sink.Monitor(accepted.get());
678 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
679 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
680 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
681
682 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700683 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
684 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000685 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
686 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
687
688 // Do an i/o operation, triggering an eventual callback.
kwibergd0d81482017-04-18 03:18:22 -0700689 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000690 char buf[1024] = {0};
691
692 EXPECT_EQ(1024, client->Send(buf, 1024));
kwibergd0d81482017-04-18 03:18:22 -0700693 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000694
695 // Shouldn't signal when blocked in a thread Send, where process_io is false.
tommie7251592017-07-14 14:44:46 -0700696 std::unique_ptr<Thread> thread(Thread::CreateWithSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000697 thread->Start();
698 Sleeper sleeper;
699 TypedMessageData<AsyncSocket*> data(client.get());
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700700 thread->Send(RTC_FROM_HERE, &sleeper, 0, &data);
kwibergd0d81482017-04-18 03:18:22 -0700701 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000702
703 // But should signal when process_io is true.
kwibergd0d81482017-04-18 03:18:22 -0700704 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200705 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000706}
707
Yves Gerey665174f2018-06-19 15:03:05 +0200708void SocketTest::TcpInternal(const IPAddress& loopback,
709 size_t data_size,
710 ptrdiff_t max_send_size) {
kwibergd0d81482017-04-18 03:18:22 -0700711 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000712 SocketAddress accept_addr;
713
jbauchf2a2bf42016-02-03 16:45:32 -0800714 // Create receiving client.
jbauch555604a2016-04-26 03:13:22 -0700715 std::unique_ptr<AsyncSocket> receiver(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000716 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800717 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000718
719 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700720 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000721 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
722 sink.Monitor(server.get());
723 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
724 EXPECT_EQ(0, server->Listen(5));
725
726 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800727 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000728
jbauchf2a2bf42016-02-03 16:45:32 -0800729 // Accept connection which will be used for sending.
kwibergd0d81482017-04-18 03:18:22 -0700730 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700731 std::unique_ptr<AsyncSocket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800732 ASSERT_TRUE(sender);
733 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000734
735 // Both sides are now connected.
jbauchf2a2bf42016-02-03 16:45:32 -0800736 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700737 EXPECT_TRUE(sink.Check(receiver.get(), SSE_OPEN));
jbauchf2a2bf42016-02-03 16:45:32 -0800738 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
739 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
740
741 // Create test data.
742 rtc::Buffer send_buffer(0, data_size);
743 rtc::Buffer recv_buffer(0, data_size);
744 for (size_t i = 0; i < data_size; ++i) {
745 char ch = static_cast<char>(i % 256);
746 send_buffer.AppendData(&ch, sizeof(ch));
747 }
danilchapb7b9dca2016-08-05 05:55:43 -0700748 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000749
750 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800751 size_t sent_size = 0;
752 bool writable = true;
753 bool send_called = false;
754 bool readable = false;
755 bool recv_called = false;
756 while (recv_buffer.size() < send_buffer.size()) {
757 // Send as much as we can while we're cleared to send.
758 while (writable && sent_size < send_buffer.size()) {
759 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
760 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
761 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000762 // The first Send() after connecting or getting writability should
763 // succeed and send some data.
764 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800765 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000766 }
767 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800768 EXPECT_LE(sent, unsent_size);
769 sent_size += sent;
770 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 05:55:43 -0700771 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-03 16:45:32 -0800772 if (sent < unsent_size) {
773 // If max_send_size is limiting the amount to send per call such
774 // that the sent amount is less than the unsent amount, we simulate
775 // that the socket is no longer writable.
776 writable = false;
777 }
778 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000779 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800780 ASSERT_TRUE(sender->IsBlocking());
781 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000782 }
783 }
784
785 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800786 while (recv_buffer.size() < sent_size) {
787 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000788 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700789 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), SSE_READ), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800790 readable = true;
791 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000792 }
793
794 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 05:55:43 -0700795 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000796
jbauchf2a2bf42016-02-03 16:45:32 -0800797 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000798 // The first Recv() after getting readability should succeed and receive
799 // some data.
800 // TODO: The following line is disabled due to flakey pulse
801 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800802 // EXPECT_GT(recved_size, 0);
803 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000804 }
jbauchf2a2bf42016-02-03 16:45:32 -0800805 if (recved_size >= 0) {
806 EXPECT_LE(static_cast<size_t>(recved_size),
Yves Gerey665174f2018-06-19 15:03:05 +0200807 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 05:55:43 -0700808 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000809 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800810 ASSERT_TRUE(receiver->IsBlocking());
811 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000812 }
813 }
814
jbauchf2a2bf42016-02-03 16:45:32 -0800815 // Once all that we've sent has been received, expect to be able to send
816 // again.
817 if (!writable) {
kwibergd0d81482017-04-18 03:18:22 -0700818 ASSERT_TRUE_WAIT(sink.Check(sender.get(), SSE_WRITE), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800819 writable = true;
820 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000821 }
822 }
823
824 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800825 EXPECT_EQ(data_size, sent_size);
826 EXPECT_EQ(data_size, recv_buffer.size());
827 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000828
829 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800830 sender->Close();
831 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700832 EXPECT_TRUE(sink.Check(receiver.get(), SSE_CLOSE));
jbauchf2a2bf42016-02-03 16:45:32 -0800833 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000834}
835
836void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700837 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000838 SocketAddress accept_addr;
839
840 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700841 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000842 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
843 sink.Monitor(client.get());
844
845 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700846 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000847 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
848 sink.Monitor(server.get());
849 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
850 EXPECT_EQ(0, server->Listen(5));
851
852 // Attempt connection.
853 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
854
855 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700856 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700857 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000858 ASSERT_TRUE(accepted);
859 sink.Monitor(accepted.get());
860
861 // Both sides are now connected.
862 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700863 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000864 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
865 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
866
867 // Expect a writable callback from the connect.
kwibergd0d81482017-04-18 03:18:22 -0700868 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000869
870 // Fill the socket buffer.
871 char buf[1024 * 16] = {0};
872 int sends = 0;
Yves Gerey665174f2018-06-19 15:03:05 +0200873 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {
874 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000875 EXPECT_TRUE(accepted->IsBlocking());
876
877 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700878 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000879
880 // Pull data.
881 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200882 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000883 }
884
885 // Expect at least one additional writable callback.
kwibergd0d81482017-04-18 03:18:22 -0700886 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000887
888 // Adding data in response to the writeable callback shouldn't cause infinite
889 // callbacks.
890 int extras = 0;
891 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800892 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000893 rtc::Thread::Current()->ProcessMessages(1);
kwibergd0d81482017-04-18 03:18:22 -0700894 if (sink.Check(accepted.get(), SSE_WRITE)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000895 extras++;
896 }
897 }
898 EXPECT_LT(extras, 2);
899
900 // Close down.
901 accepted->Close();
902 client->Close();
903}
904
905void SocketTest::UdpInternal(const IPAddress& loopback) {
906 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
907 // Test basic bind and connect behavior.
Yves Gerey665174f2018-06-19 15:03:05 +0200908 AsyncSocket* socket = ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000909 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
910 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
911 SocketAddress addr1 = socket->GetLocalAddress();
912 EXPECT_EQ(0, socket->Connect(addr1));
913 EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
914 socket->Close();
915 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
916 delete socket;
917
918 // Test send/receive behavior.
jbauch555604a2016-04-26 03:13:22 -0700919 std::unique_ptr<TestClient> client1(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200920 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, addr1))));
jbauch555604a2016-04-26 03:13:22 -0700921 std::unique_ptr<TestClient> client2(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200922 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000923
924 SocketAddress addr2;
925 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
926 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
927
928 SocketAddress addr3;
929 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
930 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
931 EXPECT_EQ(addr3, addr1);
932 // TODO: figure out what the intent is here
933 for (int i = 0; i < 10; ++i) {
nisse32f25052017-05-08 01:57:18 -0700934 client2.reset(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200935 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000936
937 SocketAddress addr4;
938 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
939 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
940 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
941
942 SocketAddress addr5;
943 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
944 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
945 EXPECT_EQ(addr5, addr1);
946
947 addr2 = addr4;
948 }
949}
950
951void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
952 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
953 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
954 // documentation.
955 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
Yves Gerey665174f2018-06-19 15:03:05 +0200956 std::string dest =
957 (loopback.family() == AF_INET6) ? "2001:db8::1" : "192.0.2.0";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000958 SocketAddress test_addr(dest, 2345);
959
960 // Test send
jbauch555604a2016-04-26 03:13:22 -0700961 std::unique_ptr<TestClient> client(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200962 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000963 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -0700964 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000965 // Init the test packet just to avoid memcheck warning.
966 memset(test_packet.get(), 0, test_packet_size);
967 // Set the send buffer size to the same size as the test packet to have a
968 // better chance to get EWOULDBLOCK.
969 int send_buffer_size = test_packet_size;
970#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
971 send_buffer_size /= 2;
972#endif
973 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
974
975 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200976 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000977 int sent_packet_num = 0;
978 int expected_error = EWOULDBLOCK;
979 while (start_ms + kTimeout > Time()) {
980 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
981 ++sent_packet_num;
982 if (ret != test_packet_size) {
983 error = client->GetError();
984 if (error == expected_error) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100985 RTC_LOG(LS_INFO) << "Got expected error code after sending "
986 << sent_packet_num << " packets.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000987 break;
988 }
989 }
990 }
991 EXPECT_EQ(expected_error, error);
992 EXPECT_FALSE(client->ready_to_send());
993 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100994 RTC_LOG(LS_INFO) << "Got SignalReadyToSend";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000995}
996
997void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
jbauch555604a2016-04-26 03:13:22 -0700998 std::unique_ptr<AsyncSocket> socket(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000999 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
1000 socket->Bind(SocketAddress(loopback, 0));
1001
1002 // Check SNDBUF/RCVBUF.
1003 const int desired_size = 12345;
1004#if defined(WEBRTC_LINUX)
1005 // Yes, really. It's in the kernel source.
1006 const int expected_size = desired_size * 2;
1007#else // !WEBRTC_LINUX
1008 const int expected_size = desired_size;
1009#endif // !WEBRTC_LINUX
1010 int recv_size = 0;
1011 int send_size = 0;
1012 // get the initial sizes
1013 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1014 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1015 // set our desired sizes
1016 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
1017 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
1018 // get the sizes again
1019 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1020 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1021 // make sure they are right
1022 ASSERT_EQ(expected_size, recv_size);
1023 ASSERT_EQ(expected_size, send_size);
1024
1025 // Check that we can't set NODELAY on a UDP socket.
1026 int current_nd, desired_nd = 1;
1027 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1028 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001029}
1030
Stefan Holmer9131efd2016-05-23 18:19:26 +02001031void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
1032 std::unique_ptr<Socket> socket(
1033 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
1034 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1035 SocketAddress address = socket->GetLocalAddress();
1036
nissedeb95f32016-11-28 01:54:54 -08001037 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001038 socket->SendTo("foo", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001039 int64_t recv_timestamp_1;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001040 char buffer[3];
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001041 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1);
1042 EXPECT_GT(recv_timestamp_1, -1);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001043
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001044 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001045 Thread::SleepMs(kTimeBetweenPacketsMs);
1046
nissedeb95f32016-11-28 01:54:54 -08001047 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001048 socket->SendTo("bar", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001049 int64_t recv_timestamp_2;
1050 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2);
1051
1052 int64_t system_time_diff = send_time_2 - send_time_1;
1053 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1054 // Compare against the system time at the point of sending, because
1055 // SleepMs may not sleep for exactly the requested time.
1056 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001057}
1058
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001059} // namespace rtc