blob: 5f6de42a2f13074a6b96bf9eeec5d8dfd31137c4 [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
jbauchf2a2bf42016-02-03 16:45:32 -080027// Data size to be used in TcpInternal tests.
28static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
29
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000030#define MAYBE_SKIP_IPV6 \
31 if (!HasIPv6Enabled()) { \
32 LOG(LS_INFO) << "No IPv6... skipping"; \
33 return; \
34 }
35
36
37void SocketTest::TestConnectIPv4() {
38 ConnectInternal(kIPv4Loopback);
39}
40
41void SocketTest::TestConnectIPv6() {
42 MAYBE_SKIP_IPV6;
43 ConnectInternal(kIPv6Loopback);
44}
45
46void SocketTest::TestConnectWithDnsLookupIPv4() {
47 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
48}
49
50void SocketTest::TestConnectWithDnsLookupIPv6() {
51 // TODO: Enable this when DNS resolution supports IPv6.
52 LOG(LS_INFO) << "Skipping IPv6 DNS test";
53 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
54}
55
56void SocketTest::TestConnectFailIPv4() {
57 ConnectFailInternal(kIPv4Loopback);
58}
59
60void SocketTest::TestConnectFailIPv6() {
61 MAYBE_SKIP_IPV6;
62 ConnectFailInternal(kIPv6Loopback);
63}
64
65void SocketTest::TestConnectWithDnsLookupFailIPv4() {
66 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
67}
68
69void SocketTest::TestConnectWithDnsLookupFailIPv6() {
70 MAYBE_SKIP_IPV6;
71 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
72}
73
74void SocketTest::TestConnectWithClosedSocketIPv4() {
75 ConnectWithClosedSocketInternal(kIPv4Loopback);
76}
77
78void SocketTest::TestConnectWithClosedSocketIPv6() {
79 MAYBE_SKIP_IPV6;
80 ConnectWithClosedSocketInternal(kIPv6Loopback);
81}
82
83void SocketTest::TestConnectWhileNotClosedIPv4() {
84 ConnectWhileNotClosedInternal(kIPv4Loopback);
85}
86
87void SocketTest::TestConnectWhileNotClosedIPv6() {
88 MAYBE_SKIP_IPV6;
89 ConnectWhileNotClosedInternal(kIPv6Loopback);
90}
91
92void SocketTest::TestServerCloseDuringConnectIPv4() {
93 ServerCloseDuringConnectInternal(kIPv4Loopback);
94}
95
96void SocketTest::TestServerCloseDuringConnectIPv6() {
97 MAYBE_SKIP_IPV6;
98 ServerCloseDuringConnectInternal(kIPv6Loopback);
99}
100
101void SocketTest::TestClientCloseDuringConnectIPv4() {
102 ClientCloseDuringConnectInternal(kIPv4Loopback);
103}
104
105void SocketTest::TestClientCloseDuringConnectIPv6() {
106 MAYBE_SKIP_IPV6;
107 ClientCloseDuringConnectInternal(kIPv6Loopback);
108}
109
110void SocketTest::TestServerCloseIPv4() {
111 ServerCloseInternal(kIPv4Loopback);
112}
113
114void SocketTest::TestServerCloseIPv6() {
115 MAYBE_SKIP_IPV6;
116 ServerCloseInternal(kIPv6Loopback);
117}
118
119void SocketTest::TestCloseInClosedCallbackIPv4() {
120 CloseInClosedCallbackInternal(kIPv4Loopback);
121}
122
123void SocketTest::TestCloseInClosedCallbackIPv6() {
124 MAYBE_SKIP_IPV6;
125 CloseInClosedCallbackInternal(kIPv6Loopback);
126}
127
128void SocketTest::TestSocketServerWaitIPv4() {
129 SocketServerWaitInternal(kIPv4Loopback);
130}
131
132void SocketTest::TestSocketServerWaitIPv6() {
133 MAYBE_SKIP_IPV6;
134 SocketServerWaitInternal(kIPv6Loopback);
135}
136
137void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800138 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000139}
140
141void SocketTest::TestTcpIPv6() {
142 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800143 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000144}
145
146void SocketTest::TestSingleFlowControlCallbackIPv4() {
147 SingleFlowControlCallbackInternal(kIPv4Loopback);
148}
149
150void SocketTest::TestSingleFlowControlCallbackIPv6() {
151 MAYBE_SKIP_IPV6;
152 SingleFlowControlCallbackInternal(kIPv6Loopback);
153}
154
155void SocketTest::TestUdpIPv4() {
156 UdpInternal(kIPv4Loopback);
157}
158
159void SocketTest::TestUdpIPv6() {
160 MAYBE_SKIP_IPV6;
161 UdpInternal(kIPv6Loopback);
162}
163
164void SocketTest::TestUdpReadyToSendIPv4() {
165#if !defined(WEBRTC_MAC)
166 // TODO(ronghuawu): Enable this test on mac/ios.
167 UdpReadyToSend(kIPv4Loopback);
168#endif
169}
170
171void SocketTest::TestUdpReadyToSendIPv6() {
172#if defined(WEBRTC_WIN)
173 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
174 MAYBE_SKIP_IPV6;
175 UdpReadyToSend(kIPv6Loopback);
176#endif
177}
178
179void SocketTest::TestGetSetOptionsIPv4() {
180 GetSetOptionsInternal(kIPv4Loopback);
181}
182
183void SocketTest::TestGetSetOptionsIPv6() {
184 MAYBE_SKIP_IPV6;
185 GetSetOptionsInternal(kIPv6Loopback);
186}
187
188// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
189// values on Windows, but an empty address of the same family on Linux/MacOS X.
190bool IsUnspecOrEmptyIP(const IPAddress& address) {
191#if !defined(WEBRTC_WIN)
192 return IPIsAny(address);
193#else
194 return address.family() == AF_UNSPEC;
195#endif
196}
197
198void SocketTest::ConnectInternal(const IPAddress& loopback) {
199 testing::StreamSink sink;
200 SocketAddress accept_addr;
201
202 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700203 std::unique_ptr<AsyncSocket> client(
204 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000205 sink.Monitor(client.get());
206 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
207 EXPECT_PRED1(IsUnspecOrEmptyIP, client->GetLocalAddress().ipaddr());
208
209 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700210 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000211 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
212 sink.Monitor(server.get());
213 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
214 EXPECT_EQ(0, server->Listen(5));
215 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
216
217 // Ensure no pending server connections, since we haven't done anything yet.
218 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
219 EXPECT_TRUE(NULL == server->Accept(&accept_addr));
220 EXPECT_TRUE(accept_addr.IsNil());
221
222 // Attempt connect to listening socket.
223 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
224 EXPECT_FALSE(client->GetLocalAddress().IsNil());
225 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
226
227 // Client is connecting, outcome not yet determined.
228 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
229 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
230 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
231
232 // Server has pending connection, accept it.
233 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700234 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000235 ASSERT_TRUE(accepted);
236 EXPECT_FALSE(accept_addr.IsNil());
237 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
238
239 // Connected from server perspective, check the addresses are correct.
240 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
241 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
242 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
243
244 // Connected from client perspective, check the addresses are correct.
245 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
246 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
247 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
248 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
249 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
250}
251
252void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
253 const std::string& host) {
254 testing::StreamSink sink;
255 SocketAddress accept_addr;
256
257 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700258 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000259 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
260 sink.Monitor(client.get());
261
262 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700263 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000264 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
265 sink.Monitor(server.get());
266 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
267 EXPECT_EQ(0, server->Listen(5));
268
269 // Attempt connect to listening socket.
270 SocketAddress dns_addr(server->GetLocalAddress());
271 dns_addr.SetIP(host);
272 EXPECT_EQ(0, client->Connect(dns_addr));
273 // TODO: Bind when doing DNS lookup.
274 //EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
275
276 // Client is connecting, outcome not yet determined.
277 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
278 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
279 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
280
281 // Server has pending connection, accept it.
282 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700283 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000284 ASSERT_TRUE(accepted);
285 EXPECT_FALSE(accept_addr.IsNil());
286 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
287
288 // Connected from server perspective, check the addresses are correct.
289 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
290 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
291 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
292
293 // Connected from client perspective, check the addresses are correct.
294 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
295 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
296 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
297 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
298 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
299}
300
301void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
302 testing::StreamSink sink;
303 SocketAddress accept_addr;
304
305 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700306 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000307 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
308 sink.Monitor(client.get());
309
310 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700311 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000312 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
313 sink.Monitor(server.get());
314 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
315
316 // Attempt connect to a non-existent socket.
317 // We don't connect to the server socket created above, since on
318 // MacOS it takes about 75 seconds to get back an error!
319 SocketAddress bogus_addr(loopback, 65535);
320 EXPECT_EQ(0, client->Connect(bogus_addr));
321
322 // Wait for connection to fail (ECONNREFUSED).
323 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
324 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
325 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
326 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
327
328 // Should be no pending server connections.
329 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
330 EXPECT_TRUE(NULL == server->Accept(&accept_addr));
331 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
332}
333
334void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
335 testing::StreamSink sink;
336 SocketAddress accept_addr;
337
338 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700339 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000340 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
341 sink.Monitor(client.get());
342
343 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700344 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000345 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
346 sink.Monitor(server.get());
347 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
348
349 // Attempt connect to a non-existent host.
350 // We don't connect to the server socket created above, since on
351 // MacOS it takes about 75 seconds to get back an error!
352 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
353 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
354
355 // Wait for connection to fail (EHOSTNOTFOUND).
356 bool dns_lookup_finished = false;
357 WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
358 dns_lookup_finished);
359 if (!dns_lookup_finished) {
360 LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
361 << "seconds.";
362 return;
363 }
364
365 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
366 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
367 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
368 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
369 // Should be no pending server connections.
370 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
371 EXPECT_TRUE(NULL == server->Accept(&accept_addr));
372 EXPECT_TRUE(accept_addr.IsNil());
373}
374
375void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
376 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700377 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000378 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
379 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
380 EXPECT_EQ(0, server->Listen(5));
381
382 // Create a client and put in to CS_CLOSED state.
jbauch555604a2016-04-26 03:13:22 -0700383 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000384 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
385 EXPECT_EQ(0, client->Close());
386 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
387
388 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
389 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
390 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
391}
392
393void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
394 // Create server and listen.
395 testing::StreamSink sink;
jbauch555604a2016-04-26 03:13:22 -0700396 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000397 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
398 sink.Monitor(server.get());
399 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
400 EXPECT_EQ(0, server->Listen(5));
401 // Create client, connect.
jbauch555604a2016-04-26 03:13:22 -0700402 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000403 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
404 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
405 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
406 // Try to connect again. Should fail, but not interfere with original attempt.
407 EXPECT_EQ(SOCKET_ERROR,
408 client->Connect(SocketAddress(server->GetLocalAddress())));
409
410 // Accept the original connection.
411 SocketAddress accept_addr;
412 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700413 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000414 ASSERT_TRUE(accepted);
415 EXPECT_FALSE(accept_addr.IsNil());
416
417 // Check the states and addresses.
418 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
419 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
420 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
421 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
422 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
423 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
424
425 // Try to connect again, to an unresolved hostname.
426 // Shouldn't break anything.
427 EXPECT_EQ(SOCKET_ERROR,
428 client->Connect(SocketAddress("localhost",
429 server->GetLocalAddress().port())));
430 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
431 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
432 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
433 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
434}
435
436void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
437 testing::StreamSink sink;
438
439 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700440 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000441 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
442 sink.Monitor(client.get());
443
444 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700445 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000446 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
447 sink.Monitor(server.get());
448 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
449 EXPECT_EQ(0, server->Listen(5));
450
451 // Attempt connect to listening socket.
452 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
453
454 // Close down the server while the socket is in the accept queue.
455 EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
456 server->Close();
457
458 // This should fail the connection for the client. Clean up.
459 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
460 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
461 client->Close();
462}
463
464void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
465 testing::StreamSink sink;
466 SocketAddress accept_addr;
467
468 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700469 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000470 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
471 sink.Monitor(client.get());
472
473 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700474 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000475 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
476 sink.Monitor(server.get());
477 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
478 EXPECT_EQ(0, server->Listen(5));
479
480 // Attempt connect to listening socket.
481 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
482
483 // Close down the client while the socket is in the accept queue.
484 EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
485 client->Close();
486
487 // The connection should still be able to be accepted.
jbauch555604a2016-04-26 03:13:22 -0700488 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000489 ASSERT_TRUE(accepted);
490 sink.Monitor(accepted.get());
491 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
492
493 // The accepted socket should then close (possibly with err, timing-related)
494 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
495 EXPECT_TRUE(sink.Check(accepted.get(), testing::SSE_CLOSE) ||
496 sink.Check(accepted.get(), testing::SSE_ERROR));
497
498 // The client should not get a close event.
499 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
500}
501
502void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
503 testing::StreamSink sink;
504 SocketAddress accept_addr;
505
506 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700507 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000508 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
509 sink.Monitor(client.get());
510
511 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700512 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000513 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
514 sink.Monitor(server.get());
515 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
516 EXPECT_EQ(0, server->Listen(5));
517
518 // Attempt connection.
519 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
520
521 // Accept connection.
522 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700523 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000524 ASSERT_TRUE(accepted);
525 sink.Monitor(accepted.get());
526
527 // Both sides are now connected.
528 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
529 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
530 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
531 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
532
533 // Send data to the client, and then close the connection.
534 EXPECT_EQ(1, accepted->Send("a", 1));
535 accepted->Close();
536 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
537
538 // Expect that the client is notified, and has not yet closed.
539 EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
540 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
541 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
542
543 // Ensure the data can be read.
544 char buffer[10];
545 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer)));
546 EXPECT_EQ('a', buffer[0]);
547
548 // Now we should close, but the remote address will remain.
549 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
550 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
551 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
552
553 // The closer should not get a close signal.
554 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_CLOSE));
555 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
556
557 // And the closee should only get a single signal.
558 Thread::Current()->ProcessMessages(0);
559 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
560
561 // Close down the client and ensure all is good.
562 client->Close();
563 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
564 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
565}
566
567class SocketCloser : public sigslot::has_slots<> {
568 public:
569 void OnClose(AsyncSocket* socket, int error) {
570 socket->Close(); // Deleting here would blow up the vector of handlers
571 // for the socket's signal.
572 }
573};
574
575void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
576 testing::StreamSink sink;
577 SocketCloser closer;
578 SocketAddress accept_addr;
579
580 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700581 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000582 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
583 sink.Monitor(client.get());
584 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
585
586 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700587 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000588 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
589 sink.Monitor(server.get());
590 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
591 EXPECT_EQ(0, server->Listen(5));
592
593 // Attempt connection.
594 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
595
596 // Accept connection.
597 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700598 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000599 ASSERT_TRUE(accepted);
600 sink.Monitor(accepted.get());
601
602 // Both sides are now connected.
603 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
604 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
605 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
606 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
607
608 // Send data to the client, and then close the connection.
609 accepted->Close();
610 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
611
612 // Expect that the client is notified, and has not yet closed.
613 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
614 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
615
616 // Now we should be closed and invalidated
617 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
618 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
619 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
620}
621
622class Sleeper : public MessageHandler {
623 public:
624 Sleeper() {}
625 void OnMessage(Message* msg) {
626 Thread::Current()->SleepMs(500);
627 }
628};
629
630void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
631 testing::StreamSink sink;
632 SocketAddress accept_addr;
633
634 // Create & connect server and client sockets.
jbauch555604a2016-04-26 03:13:22 -0700635 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000636 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauch555604a2016-04-26 03:13:22 -0700637 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000638 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
639 sink.Monitor(client.get());
640 sink.Monitor(server.get());
641 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
642 EXPECT_EQ(0, server->Listen(5));
643
644 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
645 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
646
jbauch555604a2016-04-26 03:13:22 -0700647 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000648 ASSERT_TRUE(accepted);
649 sink.Monitor(accepted.get());
650 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
651 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
652 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
653
654 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
655 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
656 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
657 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
658 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
659
660 // Do an i/o operation, triggering an eventual callback.
661 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
662 char buf[1024] = {0};
663
664 EXPECT_EQ(1024, client->Send(buf, 1024));
665 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
666
667 // Shouldn't signal when blocked in a thread Send, where process_io is false.
jbauch555604a2016-04-26 03:13:22 -0700668 std::unique_ptr<Thread> thread(new Thread());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000669 thread->Start();
670 Sleeper sleeper;
671 TypedMessageData<AsyncSocket*> data(client.get());
672 thread->Send(&sleeper, 0, &data);
673 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
674
675 // But should signal when process_io is true.
676 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), testing::SSE_READ)), kTimeout);
677 EXPECT_LT(0, accepted->Recv(buf, 1024));
678}
679
jbauchf2a2bf42016-02-03 16:45:32 -0800680void SocketTest::TcpInternal(const IPAddress& loopback, size_t data_size,
681 ssize_t max_send_size) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000682 testing::StreamSink sink;
683 SocketAddress accept_addr;
684
jbauchf2a2bf42016-02-03 16:45:32 -0800685 // Create receiving client.
jbauch555604a2016-04-26 03:13:22 -0700686 std::unique_ptr<AsyncSocket> receiver(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000687 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800688 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000689
690 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700691 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000692 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
693 sink.Monitor(server.get());
694 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
695 EXPECT_EQ(0, server->Listen(5));
696
697 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800698 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000699
jbauchf2a2bf42016-02-03 16:45:32 -0800700 // Accept connection which will be used for sending.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000701 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700702 std::unique_ptr<AsyncSocket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800703 ASSERT_TRUE(sender);
704 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000705
706 // Both sides are now connected.
jbauchf2a2bf42016-02-03 16:45:32 -0800707 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, receiver->GetState(), kTimeout);
708 EXPECT_TRUE(sink.Check(receiver.get(), testing::SSE_OPEN));
709 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
710 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
711
712 // Create test data.
713 rtc::Buffer send_buffer(0, data_size);
714 rtc::Buffer recv_buffer(0, data_size);
715 for (size_t i = 0; i < data_size; ++i) {
716 char ch = static_cast<char>(i % 256);
717 send_buffer.AppendData(&ch, sizeof(ch));
718 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000719
720 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800721 size_t sent_size = 0;
722 bool writable = true;
723 bool send_called = false;
724 bool readable = false;
725 bool recv_called = false;
726 while (recv_buffer.size() < send_buffer.size()) {
727 // Send as much as we can while we're cleared to send.
728 while (writable && sent_size < send_buffer.size()) {
729 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
730 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
731 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000732 // The first Send() after connecting or getting writability should
733 // succeed and send some data.
734 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800735 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000736 }
737 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800738 EXPECT_LE(sent, unsent_size);
739 sent_size += sent;
740 if (max_send_size >= 0) {
741 EXPECT_LE(static_cast<ssize_t>(sent), max_send_size);
742 if (sent < unsent_size) {
743 // If max_send_size is limiting the amount to send per call such
744 // that the sent amount is less than the unsent amount, we simulate
745 // that the socket is no longer writable.
746 writable = false;
747 }
748 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000749 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800750 ASSERT_TRUE(sender->IsBlocking());
751 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000752 }
753 }
754
755 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800756 while (recv_buffer.size() < sent_size) {
757 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000758 // Wait until data is available.
jbauchf2a2bf42016-02-03 16:45:32 -0800759 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), testing::SSE_READ),
760 kTimeout);
761 readable = true;
762 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000763 }
764
765 // Receive as much as we can get in a single recv call.
jbauchf2a2bf42016-02-03 16:45:32 -0800766 char recved_data[data_size];
767 int recved_size = receiver->Recv(recved_data, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000768
jbauchf2a2bf42016-02-03 16:45:32 -0800769 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000770 // The first Recv() after getting readability should succeed and receive
771 // some data.
772 // TODO: The following line is disabled due to flakey pulse
773 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800774 // EXPECT_GT(recved_size, 0);
775 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000776 }
jbauchf2a2bf42016-02-03 16:45:32 -0800777 if (recved_size >= 0) {
778 EXPECT_LE(static_cast<size_t>(recved_size),
779 sent_size - recv_buffer.size());
780 recv_buffer.AppendData(recved_data, recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000781 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800782 ASSERT_TRUE(receiver->IsBlocking());
783 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000784 }
785 }
786
jbauchf2a2bf42016-02-03 16:45:32 -0800787 // Once all that we've sent has been received, expect to be able to send
788 // again.
789 if (!writable) {
790 EXPECT_TRUE_WAIT(sink.Check(sender.get(), testing::SSE_WRITE),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000791 kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800792 writable = true;
793 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000794 }
795 }
796
797 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800798 EXPECT_EQ(data_size, sent_size);
799 EXPECT_EQ(data_size, recv_buffer.size());
800 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000801
802 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800803 sender->Close();
804 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, receiver->GetState(), kTimeout);
805 EXPECT_TRUE(sink.Check(receiver.get(), testing::SSE_CLOSE));
806 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000807}
808
809void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
810 testing::StreamSink sink;
811 SocketAddress accept_addr;
812
813 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700814 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000815 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
816 sink.Monitor(client.get());
817
818 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700819 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000820 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
821 sink.Monitor(server.get());
822 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
823 EXPECT_EQ(0, server->Listen(5));
824
825 // Attempt connection.
826 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
827
828 // Accept connection.
829 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700830 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000831 ASSERT_TRUE(accepted);
832 sink.Monitor(accepted.get());
833
834 // Both sides are now connected.
835 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
836 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
837 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
838 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
839
840 // Expect a writable callback from the connect.
841 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
842
843 // Fill the socket buffer.
844 char buf[1024 * 16] = {0};
845 int sends = 0;
tfarina5237aaf2015-11-10 23:44:30 -0800846 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000847 EXPECT_TRUE(accepted->IsBlocking());
848
849 // Wait until data is available.
850 EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
851
852 // Pull data.
853 for (int i = 0; i < sends; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800854 client->Recv(buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000855 }
856
857 // Expect at least one additional writable callback.
858 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
859
860 // Adding data in response to the writeable callback shouldn't cause infinite
861 // callbacks.
862 int extras = 0;
863 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800864 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000865 rtc::Thread::Current()->ProcessMessages(1);
866 if (sink.Check(accepted.get(), testing::SSE_WRITE)) {
867 extras++;
868 }
869 }
870 EXPECT_LT(extras, 2);
871
872 // Close down.
873 accepted->Close();
874 client->Close();
875}
876
877void SocketTest::UdpInternal(const IPAddress& loopback) {
878 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
879 // Test basic bind and connect behavior.
880 AsyncSocket* socket =
881 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
882 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
883 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
884 SocketAddress addr1 = socket->GetLocalAddress();
885 EXPECT_EQ(0, socket->Connect(addr1));
886 EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
887 socket->Close();
888 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
889 delete socket;
890
891 // Test send/receive behavior.
jbauch555604a2016-04-26 03:13:22 -0700892 std::unique_ptr<TestClient> client1(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000893 new TestClient(AsyncUDPSocket::Create(ss_, addr1)));
jbauch555604a2016-04-26 03:13:22 -0700894 std::unique_ptr<TestClient> client2(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000895 new TestClient(AsyncUDPSocket::Create(ss_, empty)));
896
897 SocketAddress addr2;
898 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
899 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
900
901 SocketAddress addr3;
902 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
903 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
904 EXPECT_EQ(addr3, addr1);
905 // TODO: figure out what the intent is here
906 for (int i = 0; i < 10; ++i) {
907 client2.reset(new TestClient(AsyncUDPSocket::Create(ss_, empty)));
908
909 SocketAddress addr4;
910 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
911 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
912 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
913
914 SocketAddress addr5;
915 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
916 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
917 EXPECT_EQ(addr5, addr1);
918
919 addr2 = addr4;
920 }
921}
922
923void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
924 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
925 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
926 // documentation.
927 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
928 std::string dest = (loopback.family() == AF_INET6) ?
929 "2001:db8::1" : "192.0.2.0";
930 SocketAddress test_addr(dest, 2345);
931
932 // Test send
jbauch555604a2016-04-26 03:13:22 -0700933 std::unique_ptr<TestClient> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000934 new TestClient(AsyncUDPSocket::Create(ss_, empty)));
935 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -0700936 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000937 // Init the test packet just to avoid memcheck warning.
938 memset(test_packet.get(), 0, test_packet_size);
939 // Set the send buffer size to the same size as the test packet to have a
940 // better chance to get EWOULDBLOCK.
941 int send_buffer_size = test_packet_size;
942#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
943 send_buffer_size /= 2;
944#endif
945 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
946
947 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200948 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000949 int sent_packet_num = 0;
950 int expected_error = EWOULDBLOCK;
951 while (start_ms + kTimeout > Time()) {
952 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
953 ++sent_packet_num;
954 if (ret != test_packet_size) {
955 error = client->GetError();
956 if (error == expected_error) {
957 LOG(LS_INFO) << "Got expected error code after sending "
958 << sent_packet_num << " packets.";
959 break;
960 }
961 }
962 }
963 EXPECT_EQ(expected_error, error);
964 EXPECT_FALSE(client->ready_to_send());
965 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
966 LOG(LS_INFO) << "Got SignalReadyToSend";
967}
968
969void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
jbauch555604a2016-04-26 03:13:22 -0700970 std::unique_ptr<AsyncSocket> socket(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000971 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
972 socket->Bind(SocketAddress(loopback, 0));
973
974 // Check SNDBUF/RCVBUF.
975 const int desired_size = 12345;
976#if defined(WEBRTC_LINUX)
977 // Yes, really. It's in the kernel source.
978 const int expected_size = desired_size * 2;
979#else // !WEBRTC_LINUX
980 const int expected_size = desired_size;
981#endif // !WEBRTC_LINUX
982 int recv_size = 0;
983 int send_size = 0;
984 // get the initial sizes
985 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
986 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
987 // set our desired sizes
988 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
989 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
990 // get the sizes again
991 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
992 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
993 // make sure they are right
994 ASSERT_EQ(expected_size, recv_size);
995 ASSERT_EQ(expected_size, send_size);
996
997 // Check that we can't set NODELAY on a UDP socket.
998 int current_nd, desired_nd = 1;
999 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1000 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
1001
1002 // Skip the esimate MTU test for IPv6 for now.
1003 if (loopback.family() != AF_INET6) {
1004 // Try estimating MTU.
jbauch555604a2016-04-26 03:13:22 -07001005 std::unique_ptr<AsyncSocket> mtu_socket(
1006 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001007 mtu_socket->Bind(SocketAddress(loopback, 0));
Peter Boström0c4e06b2015-10-07 12:23:21 +02001008 uint16_t mtu;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001009 // should fail until we connect
1010 ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
1011 mtu_socket->Connect(SocketAddress(loopback, 0));
1012#if defined(WEBRTC_WIN)
1013 // now it should succeed
1014 ASSERT_NE(-1, mtu_socket->EstimateMTU(&mtu));
1015 ASSERT_GE(mtu, 1492); // should be at least the 1492 "plateau" on localhost
1016#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
1017 // except on WEBRTC_MAC && !WEBRTC_IOS, where it's not yet implemented
1018 ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
1019#else
1020 // and the behavior seems unpredictable on Linux,
1021 // failing on the build machine
1022 // but succeeding on my Ubiquity instance.
1023#endif
1024 }
1025}
1026
1027} // namespace rtc