blob: a31cc021662cdd7093f647e8d0cef2e7c25a8507 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2007 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
jbauch555604a2016-04-26 03:13:22 -070011#include <memory>
12
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "rtc_base/socket_unittest.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000014
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "rtc_base/arraysize.h"
16#include "rtc_base/asyncudpsocket.h"
17#include "rtc_base/buffer.h"
18#include "rtc_base/gunit.h"
19#include "rtc_base/nethelpers.h"
20#include "rtc_base/ptr_util.h"
21#include "rtc_base/socketserver.h"
22#include "rtc_base/testclient.h"
23#include "rtc_base/testutils.h"
24#include "rtc_base/thread.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000025
26namespace rtc {
27
kwibergd0d81482017-04-18 03:18:22 -070028using webrtc::testing::SSE_CLOSE;
29using webrtc::testing::SSE_ERROR;
30using webrtc::testing::SSE_OPEN;
31using webrtc::testing::SSE_READ;
32using webrtc::testing::SSE_WRITE;
33using webrtc::testing::StreamSink;
34
Mirko Bonadei675513b2017-11-09 11:09:25 +010035#define MAYBE_SKIP_IPV6 \
36 if (!HasIPv6Enabled()) { \
37 RTC_LOG(LS_INFO) << "No IPv6... skipping"; \
38 return; \
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000039 }
40
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070041// Data size to be used in TcpInternal tests.
42static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000043
Steve Anton9de3aac2017-10-24 10:08:26 -070044void SocketTest::SetUp() {
45 ss_ = Thread::Current()->socketserver();
46}
47
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000048void SocketTest::TestConnectIPv4() {
49 ConnectInternal(kIPv4Loopback);
50}
51
52void SocketTest::TestConnectIPv6() {
53 MAYBE_SKIP_IPV6;
54 ConnectInternal(kIPv6Loopback);
55}
56
57void SocketTest::TestConnectWithDnsLookupIPv4() {
58 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
59}
60
61void SocketTest::TestConnectWithDnsLookupIPv6() {
62 // TODO: Enable this when DNS resolution supports IPv6.
Mirko Bonadei675513b2017-11-09 11:09:25 +010063 RTC_LOG(LS_INFO) << "Skipping IPv6 DNS test";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000064 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
65}
66
67void SocketTest::TestConnectFailIPv4() {
68 ConnectFailInternal(kIPv4Loopback);
69}
70
71void SocketTest::TestConnectFailIPv6() {
72 MAYBE_SKIP_IPV6;
73 ConnectFailInternal(kIPv6Loopback);
74}
75
76void SocketTest::TestConnectWithDnsLookupFailIPv4() {
77 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
78}
79
80void SocketTest::TestConnectWithDnsLookupFailIPv6() {
81 MAYBE_SKIP_IPV6;
82 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
83}
84
85void SocketTest::TestConnectWithClosedSocketIPv4() {
86 ConnectWithClosedSocketInternal(kIPv4Loopback);
87}
88
89void SocketTest::TestConnectWithClosedSocketIPv6() {
90 MAYBE_SKIP_IPV6;
91 ConnectWithClosedSocketInternal(kIPv6Loopback);
92}
93
94void SocketTest::TestConnectWhileNotClosedIPv4() {
95 ConnectWhileNotClosedInternal(kIPv4Loopback);
96}
97
98void SocketTest::TestConnectWhileNotClosedIPv6() {
99 MAYBE_SKIP_IPV6;
100 ConnectWhileNotClosedInternal(kIPv6Loopback);
101}
102
103void SocketTest::TestServerCloseDuringConnectIPv4() {
104 ServerCloseDuringConnectInternal(kIPv4Loopback);
105}
106
107void SocketTest::TestServerCloseDuringConnectIPv6() {
108 MAYBE_SKIP_IPV6;
109 ServerCloseDuringConnectInternal(kIPv6Loopback);
110}
111
112void SocketTest::TestClientCloseDuringConnectIPv4() {
113 ClientCloseDuringConnectInternal(kIPv4Loopback);
114}
115
116void SocketTest::TestClientCloseDuringConnectIPv6() {
117 MAYBE_SKIP_IPV6;
118 ClientCloseDuringConnectInternal(kIPv6Loopback);
119}
120
121void SocketTest::TestServerCloseIPv4() {
122 ServerCloseInternal(kIPv4Loopback);
123}
124
125void SocketTest::TestServerCloseIPv6() {
126 MAYBE_SKIP_IPV6;
127 ServerCloseInternal(kIPv6Loopback);
128}
129
130void SocketTest::TestCloseInClosedCallbackIPv4() {
131 CloseInClosedCallbackInternal(kIPv4Loopback);
132}
133
134void SocketTest::TestCloseInClosedCallbackIPv6() {
135 MAYBE_SKIP_IPV6;
136 CloseInClosedCallbackInternal(kIPv6Loopback);
137}
138
139void SocketTest::TestSocketServerWaitIPv4() {
140 SocketServerWaitInternal(kIPv4Loopback);
141}
142
143void SocketTest::TestSocketServerWaitIPv6() {
144 MAYBE_SKIP_IPV6;
145 SocketServerWaitInternal(kIPv6Loopback);
146}
147
148void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800149 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000150}
151
152void SocketTest::TestTcpIPv6() {
153 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800154 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000155}
156
157void SocketTest::TestSingleFlowControlCallbackIPv4() {
158 SingleFlowControlCallbackInternal(kIPv4Loopback);
159}
160
161void SocketTest::TestSingleFlowControlCallbackIPv6() {
162 MAYBE_SKIP_IPV6;
163 SingleFlowControlCallbackInternal(kIPv6Loopback);
164}
165
166void SocketTest::TestUdpIPv4() {
167 UdpInternal(kIPv4Loopback);
168}
169
170void SocketTest::TestUdpIPv6() {
171 MAYBE_SKIP_IPV6;
172 UdpInternal(kIPv6Loopback);
173}
174
175void SocketTest::TestUdpReadyToSendIPv4() {
176#if !defined(WEBRTC_MAC)
177 // TODO(ronghuawu): Enable this test on mac/ios.
178 UdpReadyToSend(kIPv4Loopback);
179#endif
180}
181
182void SocketTest::TestUdpReadyToSendIPv6() {
183#if defined(WEBRTC_WIN)
184 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
185 MAYBE_SKIP_IPV6;
186 UdpReadyToSend(kIPv6Loopback);
187#endif
188}
189
190void SocketTest::TestGetSetOptionsIPv4() {
191 GetSetOptionsInternal(kIPv4Loopback);
192}
193
194void SocketTest::TestGetSetOptionsIPv6() {
195 MAYBE_SKIP_IPV6;
196 GetSetOptionsInternal(kIPv6Loopback);
197}
198
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700199void SocketTest::TestSocketRecvTimestampIPv4() {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200200 SocketRecvTimestamp(kIPv4Loopback);
201}
202
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700203void SocketTest::TestSocketRecvTimestampIPv6() {
204 MAYBE_SKIP_IPV6;
205 SocketRecvTimestamp(kIPv6Loopback);
206}
207
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000208// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
209// values on Windows, but an empty address of the same family on Linux/MacOS X.
210bool IsUnspecOrEmptyIP(const IPAddress& address) {
211#if !defined(WEBRTC_WIN)
212 return IPIsAny(address);
213#else
214 return address.family() == AF_UNSPEC;
215#endif
216}
217
218void SocketTest::ConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700219 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000220 SocketAddress accept_addr;
221
222 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700223 std::unique_ptr<AsyncSocket> client(
224 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000225 sink.Monitor(client.get());
226 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
227 EXPECT_PRED1(IsUnspecOrEmptyIP, client->GetLocalAddress().ipaddr());
228
229 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700230 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000231 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
232 sink.Monitor(server.get());
233 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
234 EXPECT_EQ(0, server->Listen(5));
235 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
236
237 // Ensure no pending server connections, since we haven't done anything yet.
kwibergd0d81482017-04-18 03:18:22 -0700238 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800239 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000240 EXPECT_TRUE(accept_addr.IsNil());
241
242 // Attempt connect to listening socket.
243 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
244 EXPECT_FALSE(client->GetLocalAddress().IsNil());
245 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
246
247 // Client is connecting, outcome not yet determined.
248 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700249 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
250 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000251
252 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700253 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700254 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000255 ASSERT_TRUE(accepted);
256 EXPECT_FALSE(accept_addr.IsNil());
257 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
258
259 // Connected from server perspective, check the addresses are correct.
260 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
261 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
262 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
263
264 // Connected from client perspective, check the addresses are correct.
265 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700266 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
267 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000268 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
269 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
270}
271
272void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
273 const std::string& host) {
kwibergd0d81482017-04-18 03:18:22 -0700274 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000275 SocketAddress accept_addr;
276
277 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700278 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000279 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
280 sink.Monitor(client.get());
281
282 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700283 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000284 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
285 sink.Monitor(server.get());
286 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
287 EXPECT_EQ(0, server->Listen(5));
288
289 // Attempt connect to listening socket.
290 SocketAddress dns_addr(server->GetLocalAddress());
291 dns_addr.SetIP(host);
292 EXPECT_EQ(0, client->Connect(dns_addr));
293 // TODO: Bind when doing DNS lookup.
294 //EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
295
296 // Client is connecting, outcome not yet determined.
297 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700298 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
299 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000300
301 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700302 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700303 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000304 ASSERT_TRUE(accepted);
305 EXPECT_FALSE(accept_addr.IsNil());
306 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
307
308 // Connected from server perspective, check the addresses are correct.
309 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
310 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
311 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
312
313 // Connected from client perspective, check the addresses are correct.
314 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700315 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
316 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000317 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
318 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
319}
320
321void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700322 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000323 SocketAddress accept_addr;
324
325 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700326 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000327 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
328 sink.Monitor(client.get());
329
330 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700331 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000332 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
333 sink.Monitor(server.get());
334 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
335
336 // Attempt connect to a non-existent socket.
337 // We don't connect to the server socket created above, since on
338 // MacOS it takes about 75 seconds to get back an error!
339 SocketAddress bogus_addr(loopback, 65535);
340 EXPECT_EQ(0, client->Connect(bogus_addr));
341
342 // Wait for connection to fail (ECONNREFUSED).
343 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700344 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
345 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000346 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
347
348 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700349 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800350 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000351 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
352}
353
354void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700355 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000356 SocketAddress accept_addr;
357
358 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700359 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000360 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
361 sink.Monitor(client.get());
362
363 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700364 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000365 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
366 sink.Monitor(server.get());
367 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
368
369 // Attempt connect to a non-existent host.
370 // We don't connect to the server socket created above, since on
371 // MacOS it takes about 75 seconds to get back an error!
372 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
373 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
374
375 // Wait for connection to fail (EHOSTNOTFOUND).
376 bool dns_lookup_finished = false;
377 WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
378 dns_lookup_finished);
379 if (!dns_lookup_finished) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100380 RTC_LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
381 << "seconds.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000382 return;
383 }
384
385 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700386 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
387 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000388 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
389 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700390 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800391 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000392 EXPECT_TRUE(accept_addr.IsNil());
393}
394
395void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
396 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700397 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000398 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
399 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
400 EXPECT_EQ(0, server->Listen(5));
401
402 // Create a client and put in to CS_CLOSED state.
jbauch555604a2016-04-26 03:13:22 -0700403 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000404 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
405 EXPECT_EQ(0, client->Close());
406 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
407
408 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
409 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
410 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
411}
412
413void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
414 // Create server and listen.
kwibergd0d81482017-04-18 03:18:22 -0700415 StreamSink sink;
jbauch555604a2016-04-26 03:13:22 -0700416 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000417 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
418 sink.Monitor(server.get());
419 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
420 EXPECT_EQ(0, server->Listen(5));
421 // Create client, connect.
jbauch555604a2016-04-26 03:13:22 -0700422 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000423 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
424 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
425 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
426 // Try to connect again. Should fail, but not interfere with original attempt.
427 EXPECT_EQ(SOCKET_ERROR,
428 client->Connect(SocketAddress(server->GetLocalAddress())));
429
430 // Accept the original connection.
431 SocketAddress accept_addr;
kwibergd0d81482017-04-18 03:18:22 -0700432 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700433 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000434 ASSERT_TRUE(accepted);
435 EXPECT_FALSE(accept_addr.IsNil());
436
437 // Check the states and addresses.
438 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
439 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
440 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
441 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
442 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
443 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
444
445 // Try to connect again, to an unresolved hostname.
446 // Shouldn't break anything.
447 EXPECT_EQ(SOCKET_ERROR,
448 client->Connect(SocketAddress("localhost",
449 server->GetLocalAddress().port())));
450 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
451 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
452 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
453 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
454}
455
456void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700457 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000458
459 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700460 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000461 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
462 sink.Monitor(client.get());
463
464 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700465 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000466 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
467 sink.Monitor(server.get());
468 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
469 EXPECT_EQ(0, server->Listen(5));
470
471 // Attempt connect to listening socket.
472 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
473
474 // Close down the server while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700475 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000476 server->Close();
477
478 // This should fail the connection for the client. Clean up.
479 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700480 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000481 client->Close();
482}
483
484void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700485 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000486 SocketAddress accept_addr;
487
488 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700489 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000490 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
491 sink.Monitor(client.get());
492
493 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700494 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000495 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
496 sink.Monitor(server.get());
497 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
498 EXPECT_EQ(0, server->Listen(5));
499
500 // Attempt connect to listening socket.
501 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
502
503 // Close down the client while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700504 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000505 client->Close();
506
507 // The connection should still be able to be accepted.
jbauch555604a2016-04-26 03:13:22 -0700508 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000509 ASSERT_TRUE(accepted);
510 sink.Monitor(accepted.get());
511 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
512
513 // The accepted socket should then close (possibly with err, timing-related)
514 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700515 EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE) ||
516 sink.Check(accepted.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000517
518 // The client should not get a close event.
kwibergd0d81482017-04-18 03:18:22 -0700519 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000520}
521
522void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700523 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000524 SocketAddress accept_addr;
525
526 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700527 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000528 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
529 sink.Monitor(client.get());
530
531 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700532 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000533 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
534 sink.Monitor(server.get());
535 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
536 EXPECT_EQ(0, server->Listen(5));
537
538 // Attempt connection.
539 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
540
541 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700542 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700543 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000544 ASSERT_TRUE(accepted);
545 sink.Monitor(accepted.get());
546
547 // Both sides are now connected.
548 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700549 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000550 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
551 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
552
553 // Send data to the client, and then close the connection.
554 EXPECT_EQ(1, accepted->Send("a", 1));
555 accepted->Close();
556 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
557
558 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700559 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
560 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000561 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
562
563 // Ensure the data can be read.
564 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200565 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000566 EXPECT_EQ('a', buffer[0]);
567
568 // Now we should close, but the remote address will remain.
569 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700570 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000571 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
572
573 // The closer should not get a close signal.
kwibergd0d81482017-04-18 03:18:22 -0700574 EXPECT_FALSE(sink.Check(accepted.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000575 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
576
577 // And the closee should only get a single signal.
578 Thread::Current()->ProcessMessages(0);
kwibergd0d81482017-04-18 03:18:22 -0700579 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000580
581 // Close down the client and ensure all is good.
582 client->Close();
kwibergd0d81482017-04-18 03:18:22 -0700583 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000584 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
585}
586
587class SocketCloser : public sigslot::has_slots<> {
588 public:
589 void OnClose(AsyncSocket* socket, int error) {
590 socket->Close(); // Deleting here would blow up the vector of handlers
591 // for the socket's signal.
592 }
593};
594
595void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700596 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000597 SocketCloser closer;
598 SocketAddress accept_addr;
599
600 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700601 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000602 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
603 sink.Monitor(client.get());
604 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
605
606 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700607 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000608 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
609 sink.Monitor(server.get());
610 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
611 EXPECT_EQ(0, server->Listen(5));
612
613 // Attempt connection.
614 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
615
616 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700617 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700618 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000619 ASSERT_TRUE(accepted);
620 sink.Monitor(accepted.get());
621
622 // Both sides are now connected.
623 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700624 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000625 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
626 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
627
628 // Send data to the client, and then close the connection.
629 accepted->Close();
630 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
631
632 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700633 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000634 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
635
636 // Now we should be closed and invalidated
637 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700638 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000639 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
640}
641
642class Sleeper : public MessageHandler {
643 public:
Steve Anton9de3aac2017-10-24 10:08:26 -0700644 void OnMessage(Message* msg) override { Thread::Current()->SleepMs(500); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000645};
646
647void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700648 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000649 SocketAddress accept_addr;
650
651 // Create & connect server and client sockets.
jbauch555604a2016-04-26 03:13:22 -0700652 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000653 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauch555604a2016-04-26 03:13:22 -0700654 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000655 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
656 sink.Monitor(client.get());
657 sink.Monitor(server.get());
658 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
659 EXPECT_EQ(0, server->Listen(5));
660
661 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
kwibergd0d81482017-04-18 03:18:22 -0700662 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000663
jbauch555604a2016-04-26 03:13:22 -0700664 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000665 ASSERT_TRUE(accepted);
666 sink.Monitor(accepted.get());
667 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
668 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
669 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
670
671 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700672 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
673 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000674 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
675 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
676
677 // Do an i/o operation, triggering an eventual callback.
kwibergd0d81482017-04-18 03:18:22 -0700678 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000679 char buf[1024] = {0};
680
681 EXPECT_EQ(1024, client->Send(buf, 1024));
kwibergd0d81482017-04-18 03:18:22 -0700682 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000683
684 // Shouldn't signal when blocked in a thread Send, where process_io is false.
tommie7251592017-07-14 14:44:46 -0700685 std::unique_ptr<Thread> thread(Thread::CreateWithSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000686 thread->Start();
687 Sleeper sleeper;
688 TypedMessageData<AsyncSocket*> data(client.get());
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700689 thread->Send(RTC_FROM_HERE, &sleeper, 0, &data);
kwibergd0d81482017-04-18 03:18:22 -0700690 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000691
692 // But should signal when process_io is true.
kwibergd0d81482017-04-18 03:18:22 -0700693 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200694 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000695}
696
jbauchf2a2bf42016-02-03 16:45:32 -0800697void SocketTest::TcpInternal(const IPAddress& loopback, size_t data_size,
danilchapb7b9dca2016-08-05 05:55:43 -0700698 ptrdiff_t max_send_size) {
kwibergd0d81482017-04-18 03:18:22 -0700699 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000700 SocketAddress accept_addr;
701
jbauchf2a2bf42016-02-03 16:45:32 -0800702 // Create receiving client.
jbauch555604a2016-04-26 03:13:22 -0700703 std::unique_ptr<AsyncSocket> receiver(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000704 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800705 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000706
707 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700708 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000709 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
710 sink.Monitor(server.get());
711 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
712 EXPECT_EQ(0, server->Listen(5));
713
714 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800715 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000716
jbauchf2a2bf42016-02-03 16:45:32 -0800717 // Accept connection which will be used for sending.
kwibergd0d81482017-04-18 03:18:22 -0700718 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700719 std::unique_ptr<AsyncSocket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800720 ASSERT_TRUE(sender);
721 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000722
723 // Both sides are now connected.
jbauchf2a2bf42016-02-03 16:45:32 -0800724 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700725 EXPECT_TRUE(sink.Check(receiver.get(), SSE_OPEN));
jbauchf2a2bf42016-02-03 16:45:32 -0800726 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
727 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
728
729 // Create test data.
730 rtc::Buffer send_buffer(0, data_size);
731 rtc::Buffer recv_buffer(0, data_size);
732 for (size_t i = 0; i < data_size; ++i) {
733 char ch = static_cast<char>(i % 256);
734 send_buffer.AppendData(&ch, sizeof(ch));
735 }
danilchapb7b9dca2016-08-05 05:55:43 -0700736 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000737
738 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800739 size_t sent_size = 0;
740 bool writable = true;
741 bool send_called = false;
742 bool readable = false;
743 bool recv_called = false;
744 while (recv_buffer.size() < send_buffer.size()) {
745 // Send as much as we can while we're cleared to send.
746 while (writable && sent_size < send_buffer.size()) {
747 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
748 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
749 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000750 // The first Send() after connecting or getting writability should
751 // succeed and send some data.
752 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800753 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000754 }
755 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800756 EXPECT_LE(sent, unsent_size);
757 sent_size += sent;
758 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 05:55:43 -0700759 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-03 16:45:32 -0800760 if (sent < unsent_size) {
761 // If max_send_size is limiting the amount to send per call such
762 // that the sent amount is less than the unsent amount, we simulate
763 // that the socket is no longer writable.
764 writable = false;
765 }
766 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000767 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800768 ASSERT_TRUE(sender->IsBlocking());
769 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000770 }
771 }
772
773 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800774 while (recv_buffer.size() < sent_size) {
775 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000776 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700777 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), SSE_READ), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800778 readable = true;
779 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000780 }
781
782 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 05:55:43 -0700783 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000784
jbauchf2a2bf42016-02-03 16:45:32 -0800785 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000786 // The first Recv() after getting readability should succeed and receive
787 // some data.
788 // TODO: The following line is disabled due to flakey pulse
789 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800790 // EXPECT_GT(recved_size, 0);
791 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000792 }
jbauchf2a2bf42016-02-03 16:45:32 -0800793 if (recved_size >= 0) {
794 EXPECT_LE(static_cast<size_t>(recved_size),
795 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 05:55:43 -0700796 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000797 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800798 ASSERT_TRUE(receiver->IsBlocking());
799 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000800 }
801 }
802
jbauchf2a2bf42016-02-03 16:45:32 -0800803 // Once all that we've sent has been received, expect to be able to send
804 // again.
805 if (!writable) {
kwibergd0d81482017-04-18 03:18:22 -0700806 ASSERT_TRUE_WAIT(sink.Check(sender.get(), SSE_WRITE), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800807 writable = true;
808 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000809 }
810 }
811
812 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800813 EXPECT_EQ(data_size, sent_size);
814 EXPECT_EQ(data_size, recv_buffer.size());
815 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000816
817 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800818 sender->Close();
819 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700820 EXPECT_TRUE(sink.Check(receiver.get(), SSE_CLOSE));
jbauchf2a2bf42016-02-03 16:45:32 -0800821 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000822}
823
824void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700825 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000826 SocketAddress accept_addr;
827
828 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700829 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000830 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
831 sink.Monitor(client.get());
832
833 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700834 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000835 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
836 sink.Monitor(server.get());
837 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
838 EXPECT_EQ(0, server->Listen(5));
839
840 // Attempt connection.
841 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
842
843 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700844 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700845 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000846 ASSERT_TRUE(accepted);
847 sink.Monitor(accepted.get());
848
849 // Both sides are now connected.
850 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700851 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000852 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
853 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
854
855 // Expect a writable callback from the connect.
kwibergd0d81482017-04-18 03:18:22 -0700856 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000857
858 // Fill the socket buffer.
859 char buf[1024 * 16] = {0};
860 int sends = 0;
tfarina5237aaf2015-11-10 23:44:30 -0800861 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000862 EXPECT_TRUE(accepted->IsBlocking());
863
864 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700865 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000866
867 // Pull data.
868 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200869 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000870 }
871
872 // Expect at least one additional writable callback.
kwibergd0d81482017-04-18 03:18:22 -0700873 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000874
875 // Adding data in response to the writeable callback shouldn't cause infinite
876 // callbacks.
877 int extras = 0;
878 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800879 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000880 rtc::Thread::Current()->ProcessMessages(1);
kwibergd0d81482017-04-18 03:18:22 -0700881 if (sink.Check(accepted.get(), SSE_WRITE)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000882 extras++;
883 }
884 }
885 EXPECT_LT(extras, 2);
886
887 // Close down.
888 accepted->Close();
889 client->Close();
890}
891
892void SocketTest::UdpInternal(const IPAddress& loopback) {
893 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
894 // Test basic bind and connect behavior.
895 AsyncSocket* socket =
896 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
897 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
898 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
899 SocketAddress addr1 = socket->GetLocalAddress();
900 EXPECT_EQ(0, socket->Connect(addr1));
901 EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
902 socket->Close();
903 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
904 delete socket;
905
906 // Test send/receive behavior.
jbauch555604a2016-04-26 03:13:22 -0700907 std::unique_ptr<TestClient> client1(
nisse32f25052017-05-08 01:57:18 -0700908 new TestClient(WrapUnique(AsyncUDPSocket::Create(ss_, addr1))));
jbauch555604a2016-04-26 03:13:22 -0700909 std::unique_ptr<TestClient> client2(
nisse32f25052017-05-08 01:57:18 -0700910 new TestClient(WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000911
912 SocketAddress addr2;
913 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
914 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
915
916 SocketAddress addr3;
917 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
918 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
919 EXPECT_EQ(addr3, addr1);
920 // TODO: figure out what the intent is here
921 for (int i = 0; i < 10; ++i) {
nisse32f25052017-05-08 01:57:18 -0700922 client2.reset(
923 new TestClient(WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000924
925 SocketAddress addr4;
926 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
927 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
928 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
929
930 SocketAddress addr5;
931 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
932 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
933 EXPECT_EQ(addr5, addr1);
934
935 addr2 = addr4;
936 }
937}
938
939void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
940 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
941 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
942 // documentation.
943 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
944 std::string dest = (loopback.family() == AF_INET6) ?
945 "2001:db8::1" : "192.0.2.0";
946 SocketAddress test_addr(dest, 2345);
947
948 // Test send
jbauch555604a2016-04-26 03:13:22 -0700949 std::unique_ptr<TestClient> client(
nisse32f25052017-05-08 01:57:18 -0700950 new TestClient(WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000951 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -0700952 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000953 // Init the test packet just to avoid memcheck warning.
954 memset(test_packet.get(), 0, test_packet_size);
955 // Set the send buffer size to the same size as the test packet to have a
956 // better chance to get EWOULDBLOCK.
957 int send_buffer_size = test_packet_size;
958#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
959 send_buffer_size /= 2;
960#endif
961 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
962
963 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200964 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000965 int sent_packet_num = 0;
966 int expected_error = EWOULDBLOCK;
967 while (start_ms + kTimeout > Time()) {
968 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
969 ++sent_packet_num;
970 if (ret != test_packet_size) {
971 error = client->GetError();
972 if (error == expected_error) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100973 RTC_LOG(LS_INFO) << "Got expected error code after sending "
974 << sent_packet_num << " packets.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000975 break;
976 }
977 }
978 }
979 EXPECT_EQ(expected_error, error);
980 EXPECT_FALSE(client->ready_to_send());
981 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
Mirko Bonadei675513b2017-11-09 11:09:25 +0100982 RTC_LOG(LS_INFO) << "Got SignalReadyToSend";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000983}
984
985void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
jbauch555604a2016-04-26 03:13:22 -0700986 std::unique_ptr<AsyncSocket> socket(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000987 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
988 socket->Bind(SocketAddress(loopback, 0));
989
990 // Check SNDBUF/RCVBUF.
991 const int desired_size = 12345;
992#if defined(WEBRTC_LINUX)
993 // Yes, really. It's in the kernel source.
994 const int expected_size = desired_size * 2;
995#else // !WEBRTC_LINUX
996 const int expected_size = desired_size;
997#endif // !WEBRTC_LINUX
998 int recv_size = 0;
999 int send_size = 0;
1000 // get the initial sizes
1001 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1002 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1003 // set our desired sizes
1004 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
1005 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
1006 // get the sizes again
1007 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1008 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1009 // make sure they are right
1010 ASSERT_EQ(expected_size, recv_size);
1011 ASSERT_EQ(expected_size, send_size);
1012
1013 // Check that we can't set NODELAY on a UDP socket.
1014 int current_nd, desired_nd = 1;
1015 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1016 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001017}
1018
Stefan Holmer9131efd2016-05-23 18:19:26 +02001019void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
1020 std::unique_ptr<Socket> socket(
1021 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
1022 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1023 SocketAddress address = socket->GetLocalAddress();
1024
nissedeb95f32016-11-28 01:54:54 -08001025 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001026 socket->SendTo("foo", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001027 int64_t recv_timestamp_1;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001028 char buffer[3];
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001029 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1);
1030 EXPECT_GT(recv_timestamp_1, -1);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001031
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001032 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001033 Thread::SleepMs(kTimeBetweenPacketsMs);
1034
nissedeb95f32016-11-28 01:54:54 -08001035 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001036 socket->SendTo("bar", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001037 int64_t recv_timestamp_2;
1038 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2);
1039
1040 int64_t system_time_diff = send_time_2 - send_time_1;
1041 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1042 // Compare against the system time at the point of sending, because
1043 // SleepMs may not sleep for exactly the requested time.
1044 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001045}
1046
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001047} // namespace rtc