blob: 762a88a42a5ef01d8edfb805ba77cba5d31e51b9 [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
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000013#include "webrtc/base/socket_unittest.h"
14
tfarina5237aaf2015-11-10 23:44:30 -080015#include "webrtc/base/arraysize.h"
jbauchf2a2bf42016-02-03 16:45:32 -080016#include "webrtc/base/buffer.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000017#include "webrtc/base/asyncudpsocket.h"
18#include "webrtc/base/gunit.h"
19#include "webrtc/base/nethelpers.h"
20#include "webrtc/base/socketserver.h"
21#include "webrtc/base/testclient.h"
22#include "webrtc/base/testutils.h"
23#include "webrtc/base/thread.h"
24
25namespace rtc {
26
kwibergd0d81482017-04-18 03:18:22 -070027using webrtc::testing::SSE_CLOSE;
28using webrtc::testing::SSE_ERROR;
29using webrtc::testing::SSE_OPEN;
30using webrtc::testing::SSE_READ;
31using webrtc::testing::SSE_WRITE;
32using webrtc::testing::StreamSink;
33
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000034#define MAYBE_SKIP_IPV6 \
35 if (!HasIPv6Enabled()) { \
36 LOG(LS_INFO) << "No IPv6... skipping"; \
37 return; \
38 }
39
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070040// Data size to be used in TcpInternal tests.
41static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000042
43void SocketTest::TestConnectIPv4() {
44 ConnectInternal(kIPv4Loopback);
45}
46
47void SocketTest::TestConnectIPv6() {
48 MAYBE_SKIP_IPV6;
49 ConnectInternal(kIPv6Loopback);
50}
51
52void SocketTest::TestConnectWithDnsLookupIPv4() {
53 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
54}
55
56void SocketTest::TestConnectWithDnsLookupIPv6() {
57 // TODO: Enable this when DNS resolution supports IPv6.
58 LOG(LS_INFO) << "Skipping IPv6 DNS test";
59 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
60}
61
62void SocketTest::TestConnectFailIPv4() {
63 ConnectFailInternal(kIPv4Loopback);
64}
65
66void SocketTest::TestConnectFailIPv6() {
67 MAYBE_SKIP_IPV6;
68 ConnectFailInternal(kIPv6Loopback);
69}
70
71void SocketTest::TestConnectWithDnsLookupFailIPv4() {
72 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
73}
74
75void SocketTest::TestConnectWithDnsLookupFailIPv6() {
76 MAYBE_SKIP_IPV6;
77 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
78}
79
80void SocketTest::TestConnectWithClosedSocketIPv4() {
81 ConnectWithClosedSocketInternal(kIPv4Loopback);
82}
83
84void SocketTest::TestConnectWithClosedSocketIPv6() {
85 MAYBE_SKIP_IPV6;
86 ConnectWithClosedSocketInternal(kIPv6Loopback);
87}
88
89void SocketTest::TestConnectWhileNotClosedIPv4() {
90 ConnectWhileNotClosedInternal(kIPv4Loopback);
91}
92
93void SocketTest::TestConnectWhileNotClosedIPv6() {
94 MAYBE_SKIP_IPV6;
95 ConnectWhileNotClosedInternal(kIPv6Loopback);
96}
97
98void SocketTest::TestServerCloseDuringConnectIPv4() {
99 ServerCloseDuringConnectInternal(kIPv4Loopback);
100}
101
102void SocketTest::TestServerCloseDuringConnectIPv6() {
103 MAYBE_SKIP_IPV6;
104 ServerCloseDuringConnectInternal(kIPv6Loopback);
105}
106
107void SocketTest::TestClientCloseDuringConnectIPv4() {
108 ClientCloseDuringConnectInternal(kIPv4Loopback);
109}
110
111void SocketTest::TestClientCloseDuringConnectIPv6() {
112 MAYBE_SKIP_IPV6;
113 ClientCloseDuringConnectInternal(kIPv6Loopback);
114}
115
116void SocketTest::TestServerCloseIPv4() {
117 ServerCloseInternal(kIPv4Loopback);
118}
119
120void SocketTest::TestServerCloseIPv6() {
121 MAYBE_SKIP_IPV6;
122 ServerCloseInternal(kIPv6Loopback);
123}
124
125void SocketTest::TestCloseInClosedCallbackIPv4() {
126 CloseInClosedCallbackInternal(kIPv4Loopback);
127}
128
129void SocketTest::TestCloseInClosedCallbackIPv6() {
130 MAYBE_SKIP_IPV6;
131 CloseInClosedCallbackInternal(kIPv6Loopback);
132}
133
134void SocketTest::TestSocketServerWaitIPv4() {
135 SocketServerWaitInternal(kIPv4Loopback);
136}
137
138void SocketTest::TestSocketServerWaitIPv6() {
139 MAYBE_SKIP_IPV6;
140 SocketServerWaitInternal(kIPv6Loopback);
141}
142
143void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800144 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000145}
146
147void SocketTest::TestTcpIPv6() {
148 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800149 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000150}
151
152void SocketTest::TestSingleFlowControlCallbackIPv4() {
153 SingleFlowControlCallbackInternal(kIPv4Loopback);
154}
155
156void SocketTest::TestSingleFlowControlCallbackIPv6() {
157 MAYBE_SKIP_IPV6;
158 SingleFlowControlCallbackInternal(kIPv6Loopback);
159}
160
161void SocketTest::TestUdpIPv4() {
162 UdpInternal(kIPv4Loopback);
163}
164
165void SocketTest::TestUdpIPv6() {
166 MAYBE_SKIP_IPV6;
167 UdpInternal(kIPv6Loopback);
168}
169
170void SocketTest::TestUdpReadyToSendIPv4() {
171#if !defined(WEBRTC_MAC)
172 // TODO(ronghuawu): Enable this test on mac/ios.
173 UdpReadyToSend(kIPv4Loopback);
174#endif
175}
176
177void SocketTest::TestUdpReadyToSendIPv6() {
178#if defined(WEBRTC_WIN)
179 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
180 MAYBE_SKIP_IPV6;
181 UdpReadyToSend(kIPv6Loopback);
182#endif
183}
184
185void SocketTest::TestGetSetOptionsIPv4() {
186 GetSetOptionsInternal(kIPv4Loopback);
187}
188
189void SocketTest::TestGetSetOptionsIPv6() {
190 MAYBE_SKIP_IPV6;
191 GetSetOptionsInternal(kIPv6Loopback);
192}
193
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700194void SocketTest::TestSocketRecvTimestampIPv4() {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200195 SocketRecvTimestamp(kIPv4Loopback);
196}
197
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700198void SocketTest::TestSocketRecvTimestampIPv6() {
199 MAYBE_SKIP_IPV6;
200 SocketRecvTimestamp(kIPv6Loopback);
201}
202
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000203// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
204// values on Windows, but an empty address of the same family on Linux/MacOS X.
205bool IsUnspecOrEmptyIP(const IPAddress& address) {
206#if !defined(WEBRTC_WIN)
207 return IPIsAny(address);
208#else
209 return address.family() == AF_UNSPEC;
210#endif
211}
212
213void SocketTest::ConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700214 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000215 SocketAddress accept_addr;
216
217 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700218 std::unique_ptr<AsyncSocket> client(
219 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000220 sink.Monitor(client.get());
221 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
222 EXPECT_PRED1(IsUnspecOrEmptyIP, client->GetLocalAddress().ipaddr());
223
224 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700225 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000226 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
227 sink.Monitor(server.get());
228 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
229 EXPECT_EQ(0, server->Listen(5));
230 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
231
232 // Ensure no pending server connections, since we haven't done anything yet.
kwibergd0d81482017-04-18 03:18:22 -0700233 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800234 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000235 EXPECT_TRUE(accept_addr.IsNil());
236
237 // Attempt connect to listening socket.
238 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
239 EXPECT_FALSE(client->GetLocalAddress().IsNil());
240 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
241
242 // Client is connecting, outcome not yet determined.
243 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700244 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
245 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000246
247 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700248 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700249 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000250 ASSERT_TRUE(accepted);
251 EXPECT_FALSE(accept_addr.IsNil());
252 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
253
254 // Connected from server perspective, check the addresses are correct.
255 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
256 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
257 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
258
259 // Connected from client perspective, check the addresses are correct.
260 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700261 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
262 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000263 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
264 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
265}
266
267void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
268 const std::string& host) {
kwibergd0d81482017-04-18 03:18:22 -0700269 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000270 SocketAddress accept_addr;
271
272 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700273 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000274 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
275 sink.Monitor(client.get());
276
277 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700278 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000279 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
280 sink.Monitor(server.get());
281 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
282 EXPECT_EQ(0, server->Listen(5));
283
284 // Attempt connect to listening socket.
285 SocketAddress dns_addr(server->GetLocalAddress());
286 dns_addr.SetIP(host);
287 EXPECT_EQ(0, client->Connect(dns_addr));
288 // TODO: Bind when doing DNS lookup.
289 //EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
290
291 // Client is connecting, outcome not yet determined.
292 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700293 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
294 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000295
296 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700297 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700298 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000299 ASSERT_TRUE(accepted);
300 EXPECT_FALSE(accept_addr.IsNil());
301 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
302
303 // Connected from server perspective, check the addresses are correct.
304 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
305 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
306 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
307
308 // Connected from client perspective, check the addresses are correct.
309 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700310 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
311 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000312 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
313 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
314}
315
316void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700317 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000318 SocketAddress accept_addr;
319
320 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700321 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000322 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
323 sink.Monitor(client.get());
324
325 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700326 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000327 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
328 sink.Monitor(server.get());
329 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
330
331 // Attempt connect to a non-existent socket.
332 // We don't connect to the server socket created above, since on
333 // MacOS it takes about 75 seconds to get back an error!
334 SocketAddress bogus_addr(loopback, 65535);
335 EXPECT_EQ(0, client->Connect(bogus_addr));
336
337 // Wait for connection to fail (ECONNREFUSED).
338 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700339 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
340 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000341 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
342
343 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700344 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800345 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000346 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
347}
348
349void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700350 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000351 SocketAddress accept_addr;
352
353 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700354 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000355 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
356 sink.Monitor(client.get());
357
358 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700359 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000360 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
361 sink.Monitor(server.get());
362 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
363
364 // Attempt connect to a non-existent host.
365 // We don't connect to the server socket created above, since on
366 // MacOS it takes about 75 seconds to get back an error!
367 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
368 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
369
370 // Wait for connection to fail (EHOSTNOTFOUND).
371 bool dns_lookup_finished = false;
372 WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
373 dns_lookup_finished);
374 if (!dns_lookup_finished) {
375 LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
376 << "seconds.";
377 return;
378 }
379
380 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700381 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
382 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000383 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
384 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700385 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800386 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000387 EXPECT_TRUE(accept_addr.IsNil());
388}
389
390void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
391 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700392 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000393 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
394 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
395 EXPECT_EQ(0, server->Listen(5));
396
397 // Create a client and put in to CS_CLOSED state.
jbauch555604a2016-04-26 03:13:22 -0700398 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000399 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
400 EXPECT_EQ(0, client->Close());
401 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
402
403 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
404 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
405 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
406}
407
408void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
409 // Create server and listen.
kwibergd0d81482017-04-18 03:18:22 -0700410 StreamSink sink;
jbauch555604a2016-04-26 03:13:22 -0700411 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000412 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
413 sink.Monitor(server.get());
414 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
415 EXPECT_EQ(0, server->Listen(5));
416 // Create client, connect.
jbauch555604a2016-04-26 03:13:22 -0700417 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000418 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
419 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
420 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
421 // Try to connect again. Should fail, but not interfere with original attempt.
422 EXPECT_EQ(SOCKET_ERROR,
423 client->Connect(SocketAddress(server->GetLocalAddress())));
424
425 // Accept the original connection.
426 SocketAddress accept_addr;
kwibergd0d81482017-04-18 03:18:22 -0700427 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700428 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000429 ASSERT_TRUE(accepted);
430 EXPECT_FALSE(accept_addr.IsNil());
431
432 // Check the states and addresses.
433 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
434 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
435 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
436 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
437 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
438 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
439
440 // Try to connect again, to an unresolved hostname.
441 // Shouldn't break anything.
442 EXPECT_EQ(SOCKET_ERROR,
443 client->Connect(SocketAddress("localhost",
444 server->GetLocalAddress().port())));
445 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
446 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
447 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
448 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
449}
450
451void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700452 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000453
454 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700455 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000456 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
457 sink.Monitor(client.get());
458
459 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700460 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000461 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
462 sink.Monitor(server.get());
463 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
464 EXPECT_EQ(0, server->Listen(5));
465
466 // Attempt connect to listening socket.
467 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
468
469 // Close down the server while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700470 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000471 server->Close();
472
473 // This should fail the connection for the client. Clean up.
474 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700475 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000476 client->Close();
477}
478
479void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700480 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000481 SocketAddress accept_addr;
482
483 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700484 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000485 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
486 sink.Monitor(client.get());
487
488 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700489 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000490 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
491 sink.Monitor(server.get());
492 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
493 EXPECT_EQ(0, server->Listen(5));
494
495 // Attempt connect to listening socket.
496 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
497
498 // Close down the client while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700499 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000500 client->Close();
501
502 // The connection should still be able to be accepted.
jbauch555604a2016-04-26 03:13:22 -0700503 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000504 ASSERT_TRUE(accepted);
505 sink.Monitor(accepted.get());
506 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
507
508 // The accepted socket should then close (possibly with err, timing-related)
509 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700510 EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE) ||
511 sink.Check(accepted.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000512
513 // The client should not get a close event.
kwibergd0d81482017-04-18 03:18:22 -0700514 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000515}
516
517void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700518 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000519 SocketAddress accept_addr;
520
521 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700522 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000523 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
524 sink.Monitor(client.get());
525
526 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700527 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000528 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
529 sink.Monitor(server.get());
530 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
531 EXPECT_EQ(0, server->Listen(5));
532
533 // Attempt connection.
534 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
535
536 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700537 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700538 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000539 ASSERT_TRUE(accepted);
540 sink.Monitor(accepted.get());
541
542 // Both sides are now connected.
543 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700544 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000545 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
546 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
547
548 // Send data to the client, and then close the connection.
549 EXPECT_EQ(1, accepted->Send("a", 1));
550 accepted->Close();
551 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
552
553 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700554 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
555 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000556 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
557
558 // Ensure the data can be read.
559 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200560 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000561 EXPECT_EQ('a', buffer[0]);
562
563 // Now we should close, but the remote address will remain.
564 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700565 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000566 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
567
568 // The closer should not get a close signal.
kwibergd0d81482017-04-18 03:18:22 -0700569 EXPECT_FALSE(sink.Check(accepted.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000570 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
571
572 // And the closee should only get a single signal.
573 Thread::Current()->ProcessMessages(0);
kwibergd0d81482017-04-18 03:18:22 -0700574 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000575
576 // Close down the client and ensure all is good.
577 client->Close();
kwibergd0d81482017-04-18 03:18:22 -0700578 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000579 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
580}
581
582class SocketCloser : public sigslot::has_slots<> {
583 public:
584 void OnClose(AsyncSocket* socket, int error) {
585 socket->Close(); // Deleting here would blow up the vector of handlers
586 // for the socket's signal.
587 }
588};
589
590void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700591 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000592 SocketCloser closer;
593 SocketAddress accept_addr;
594
595 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700596 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000597 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
598 sink.Monitor(client.get());
599 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
600
601 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700602 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000603 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
604 sink.Monitor(server.get());
605 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
606 EXPECT_EQ(0, server->Listen(5));
607
608 // Attempt connection.
609 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
610
611 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700612 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700613 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000614 ASSERT_TRUE(accepted);
615 sink.Monitor(accepted.get());
616
617 // Both sides are now connected.
618 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700619 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000620 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
621 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
622
623 // Send data to the client, and then close the connection.
624 accepted->Close();
625 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
626
627 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700628 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000629 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
630
631 // Now we should be closed and invalidated
632 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700633 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000634 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
635}
636
637class Sleeper : public MessageHandler {
638 public:
639 Sleeper() {}
640 void OnMessage(Message* msg) {
641 Thread::Current()->SleepMs(500);
642 }
643};
644
645void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700646 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000647 SocketAddress accept_addr;
648
649 // Create & connect server and client sockets.
jbauch555604a2016-04-26 03:13:22 -0700650 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000651 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauch555604a2016-04-26 03:13:22 -0700652 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000653 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
654 sink.Monitor(client.get());
655 sink.Monitor(server.get());
656 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
657 EXPECT_EQ(0, server->Listen(5));
658
659 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
kwibergd0d81482017-04-18 03:18:22 -0700660 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000661
jbauch555604a2016-04-26 03:13:22 -0700662 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000663 ASSERT_TRUE(accepted);
664 sink.Monitor(accepted.get());
665 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
666 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
667 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
668
669 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700670 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
671 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000672 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
673 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
674
675 // Do an i/o operation, triggering an eventual callback.
kwibergd0d81482017-04-18 03:18:22 -0700676 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000677 char buf[1024] = {0};
678
679 EXPECT_EQ(1024, client->Send(buf, 1024));
kwibergd0d81482017-04-18 03:18:22 -0700680 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000681
682 // Shouldn't signal when blocked in a thread Send, where process_io is false.
jbauch555604a2016-04-26 03:13:22 -0700683 std::unique_ptr<Thread> thread(new Thread());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000684 thread->Start();
685 Sleeper sleeper;
686 TypedMessageData<AsyncSocket*> data(client.get());
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700687 thread->Send(RTC_FROM_HERE, &sleeper, 0, &data);
kwibergd0d81482017-04-18 03:18:22 -0700688 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000689
690 // But should signal when process_io is true.
kwibergd0d81482017-04-18 03:18:22 -0700691 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200692 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000693}
694
jbauchf2a2bf42016-02-03 16:45:32 -0800695void SocketTest::TcpInternal(const IPAddress& loopback, size_t data_size,
danilchapb7b9dca2016-08-05 05:55:43 -0700696 ptrdiff_t max_send_size) {
kwibergd0d81482017-04-18 03:18:22 -0700697 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000698 SocketAddress accept_addr;
699
jbauchf2a2bf42016-02-03 16:45:32 -0800700 // Create receiving client.
jbauch555604a2016-04-26 03:13:22 -0700701 std::unique_ptr<AsyncSocket> receiver(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000702 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800703 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000704
705 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700706 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000707 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
708 sink.Monitor(server.get());
709 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
710 EXPECT_EQ(0, server->Listen(5));
711
712 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800713 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000714
jbauchf2a2bf42016-02-03 16:45:32 -0800715 // Accept connection which will be used for sending.
kwibergd0d81482017-04-18 03:18:22 -0700716 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700717 std::unique_ptr<AsyncSocket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800718 ASSERT_TRUE(sender);
719 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000720
721 // Both sides are now connected.
jbauchf2a2bf42016-02-03 16:45:32 -0800722 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700723 EXPECT_TRUE(sink.Check(receiver.get(), SSE_OPEN));
jbauchf2a2bf42016-02-03 16:45:32 -0800724 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
725 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
726
727 // Create test data.
728 rtc::Buffer send_buffer(0, data_size);
729 rtc::Buffer recv_buffer(0, data_size);
730 for (size_t i = 0; i < data_size; ++i) {
731 char ch = static_cast<char>(i % 256);
732 send_buffer.AppendData(&ch, sizeof(ch));
733 }
danilchapb7b9dca2016-08-05 05:55:43 -0700734 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000735
736 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800737 size_t sent_size = 0;
738 bool writable = true;
739 bool send_called = false;
740 bool readable = false;
741 bool recv_called = false;
742 while (recv_buffer.size() < send_buffer.size()) {
743 // Send as much as we can while we're cleared to send.
744 while (writable && sent_size < send_buffer.size()) {
745 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
746 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
747 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000748 // The first Send() after connecting or getting writability should
749 // succeed and send some data.
750 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800751 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000752 }
753 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800754 EXPECT_LE(sent, unsent_size);
755 sent_size += sent;
756 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 05:55:43 -0700757 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-03 16:45:32 -0800758 if (sent < unsent_size) {
759 // If max_send_size is limiting the amount to send per call such
760 // that the sent amount is less than the unsent amount, we simulate
761 // that the socket is no longer writable.
762 writable = false;
763 }
764 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000765 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800766 ASSERT_TRUE(sender->IsBlocking());
767 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000768 }
769 }
770
771 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800772 while (recv_buffer.size() < sent_size) {
773 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000774 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700775 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), SSE_READ), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800776 readable = true;
777 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000778 }
779
780 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 05:55:43 -0700781 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000782
jbauchf2a2bf42016-02-03 16:45:32 -0800783 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000784 // The first Recv() after getting readability should succeed and receive
785 // some data.
786 // TODO: The following line is disabled due to flakey pulse
787 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800788 // EXPECT_GT(recved_size, 0);
789 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000790 }
jbauchf2a2bf42016-02-03 16:45:32 -0800791 if (recved_size >= 0) {
792 EXPECT_LE(static_cast<size_t>(recved_size),
793 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 05:55:43 -0700794 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000795 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800796 ASSERT_TRUE(receiver->IsBlocking());
797 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000798 }
799 }
800
jbauchf2a2bf42016-02-03 16:45:32 -0800801 // Once all that we've sent has been received, expect to be able to send
802 // again.
803 if (!writable) {
kwibergd0d81482017-04-18 03:18:22 -0700804 ASSERT_TRUE_WAIT(sink.Check(sender.get(), SSE_WRITE), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800805 writable = true;
806 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000807 }
808 }
809
810 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800811 EXPECT_EQ(data_size, sent_size);
812 EXPECT_EQ(data_size, recv_buffer.size());
813 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000814
815 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800816 sender->Close();
817 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700818 EXPECT_TRUE(sink.Check(receiver.get(), SSE_CLOSE));
jbauchf2a2bf42016-02-03 16:45:32 -0800819 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000820}
821
822void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700823 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000824 SocketAddress accept_addr;
825
826 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700827 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000828 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
829 sink.Monitor(client.get());
830
831 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700832 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000833 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
834 sink.Monitor(server.get());
835 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
836 EXPECT_EQ(0, server->Listen(5));
837
838 // Attempt connection.
839 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
840
841 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700842 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700843 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000844 ASSERT_TRUE(accepted);
845 sink.Monitor(accepted.get());
846
847 // Both sides are now connected.
848 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700849 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000850 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
851 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
852
853 // Expect a writable callback from the connect.
kwibergd0d81482017-04-18 03:18:22 -0700854 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000855
856 // Fill the socket buffer.
857 char buf[1024 * 16] = {0};
858 int sends = 0;
tfarina5237aaf2015-11-10 23:44:30 -0800859 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000860 EXPECT_TRUE(accepted->IsBlocking());
861
862 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700863 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000864
865 // Pull data.
866 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200867 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000868 }
869
870 // Expect at least one additional writable callback.
kwibergd0d81482017-04-18 03:18:22 -0700871 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000872
873 // Adding data in response to the writeable callback shouldn't cause infinite
874 // callbacks.
875 int extras = 0;
876 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800877 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000878 rtc::Thread::Current()->ProcessMessages(1);
kwibergd0d81482017-04-18 03:18:22 -0700879 if (sink.Check(accepted.get(), SSE_WRITE)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000880 extras++;
881 }
882 }
883 EXPECT_LT(extras, 2);
884
885 // Close down.
886 accepted->Close();
887 client->Close();
888}
889
890void SocketTest::UdpInternal(const IPAddress& loopback) {
891 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
892 // Test basic bind and connect behavior.
893 AsyncSocket* socket =
894 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
895 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
896 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
897 SocketAddress addr1 = socket->GetLocalAddress();
898 EXPECT_EQ(0, socket->Connect(addr1));
899 EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
900 socket->Close();
901 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
902 delete socket;
903
904 // Test send/receive behavior.
jbauch555604a2016-04-26 03:13:22 -0700905 std::unique_ptr<TestClient> client1(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000906 new TestClient(AsyncUDPSocket::Create(ss_, addr1)));
jbauch555604a2016-04-26 03:13:22 -0700907 std::unique_ptr<TestClient> client2(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000908 new TestClient(AsyncUDPSocket::Create(ss_, empty)));
909
910 SocketAddress addr2;
911 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
912 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
913
914 SocketAddress addr3;
915 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
916 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
917 EXPECT_EQ(addr3, addr1);
918 // TODO: figure out what the intent is here
919 for (int i = 0; i < 10; ++i) {
920 client2.reset(new TestClient(AsyncUDPSocket::Create(ss_, empty)));
921
922 SocketAddress addr4;
923 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
924 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
925 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
926
927 SocketAddress addr5;
928 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
929 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
930 EXPECT_EQ(addr5, addr1);
931
932 addr2 = addr4;
933 }
934}
935
936void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
937 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
938 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
939 // documentation.
940 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
941 std::string dest = (loopback.family() == AF_INET6) ?
942 "2001:db8::1" : "192.0.2.0";
943 SocketAddress test_addr(dest, 2345);
944
945 // Test send
jbauch555604a2016-04-26 03:13:22 -0700946 std::unique_ptr<TestClient> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000947 new TestClient(AsyncUDPSocket::Create(ss_, empty)));
948 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -0700949 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000950 // Init the test packet just to avoid memcheck warning.
951 memset(test_packet.get(), 0, test_packet_size);
952 // Set the send buffer size to the same size as the test packet to have a
953 // better chance to get EWOULDBLOCK.
954 int send_buffer_size = test_packet_size;
955#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
956 send_buffer_size /= 2;
957#endif
958 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
959
960 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200961 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000962 int sent_packet_num = 0;
963 int expected_error = EWOULDBLOCK;
964 while (start_ms + kTimeout > Time()) {
965 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
966 ++sent_packet_num;
967 if (ret != test_packet_size) {
968 error = client->GetError();
969 if (error == expected_error) {
970 LOG(LS_INFO) << "Got expected error code after sending "
971 << sent_packet_num << " packets.";
972 break;
973 }
974 }
975 }
976 EXPECT_EQ(expected_error, error);
977 EXPECT_FALSE(client->ready_to_send());
978 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
979 LOG(LS_INFO) << "Got SignalReadyToSend";
980}
981
982void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
jbauch555604a2016-04-26 03:13:22 -0700983 std::unique_ptr<AsyncSocket> socket(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000984 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
985 socket->Bind(SocketAddress(loopback, 0));
986
987 // Check SNDBUF/RCVBUF.
988 const int desired_size = 12345;
989#if defined(WEBRTC_LINUX)
990 // Yes, really. It's in the kernel source.
991 const int expected_size = desired_size * 2;
992#else // !WEBRTC_LINUX
993 const int expected_size = desired_size;
994#endif // !WEBRTC_LINUX
995 int recv_size = 0;
996 int send_size = 0;
997 // get the initial sizes
998 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
999 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1000 // set our desired sizes
1001 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
1002 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
1003 // get the sizes again
1004 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1005 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1006 // make sure they are right
1007 ASSERT_EQ(expected_size, recv_size);
1008 ASSERT_EQ(expected_size, send_size);
1009
1010 // Check that we can't set NODELAY on a UDP socket.
1011 int current_nd, desired_nd = 1;
1012 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1013 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
1014
1015 // Skip the esimate MTU test for IPv6 for now.
1016 if (loopback.family() != AF_INET6) {
1017 // Try estimating MTU.
jbauch555604a2016-04-26 03:13:22 -07001018 std::unique_ptr<AsyncSocket> mtu_socket(
1019 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001020 mtu_socket->Bind(SocketAddress(loopback, 0));
Peter Boström0c4e06b2015-10-07 12:23:21 +02001021 uint16_t mtu;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001022 // should fail until we connect
1023 ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
1024 mtu_socket->Connect(SocketAddress(loopback, 0));
1025#if defined(WEBRTC_WIN)
1026 // now it should succeed
1027 ASSERT_NE(-1, mtu_socket->EstimateMTU(&mtu));
1028 ASSERT_GE(mtu, 1492); // should be at least the 1492 "plateau" on localhost
1029#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
1030 // except on WEBRTC_MAC && !WEBRTC_IOS, where it's not yet implemented
1031 ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
1032#else
1033 // and the behavior seems unpredictable on Linux,
1034 // failing on the build machine
1035 // but succeeding on my Ubiquity instance.
1036#endif
1037 }
1038}
1039
Stefan Holmer9131efd2016-05-23 18:19:26 +02001040void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
1041 std::unique_ptr<Socket> socket(
1042 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
1043 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1044 SocketAddress address = socket->GetLocalAddress();
1045
nissedeb95f32016-11-28 01:54:54 -08001046 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001047 socket->SendTo("foo", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001048 int64_t recv_timestamp_1;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001049 char buffer[3];
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001050 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1);
1051 EXPECT_GT(recv_timestamp_1, -1);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001052
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001053 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001054 Thread::SleepMs(kTimeBetweenPacketsMs);
1055
nissedeb95f32016-11-28 01:54:54 -08001056 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001057 socket->SendTo("bar", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001058 int64_t recv_timestamp_2;
1059 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2);
1060
1061 int64_t system_time_diff = send_time_2 - send_time_1;
1062 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1063 // Compare against the system time at the point of sending, because
1064 // SleepMs may not sleep for exactly the requested time.
1065 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001066}
1067
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001068} // namespace rtc