blob: 718903d538ad7358de305e7e0172edff003b6028 [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
27#define MAYBE_SKIP_IPV6 \
28 if (!HasIPv6Enabled()) { \
29 LOG(LS_INFO) << "No IPv6... skipping"; \
30 return; \
31 }
32
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070033// Data size to be used in TcpInternal tests.
34static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000035
36void SocketTest::TestConnectIPv4() {
37 ConnectInternal(kIPv4Loopback);
38}
39
40void SocketTest::TestConnectIPv6() {
41 MAYBE_SKIP_IPV6;
42 ConnectInternal(kIPv6Loopback);
43}
44
45void SocketTest::TestConnectWithDnsLookupIPv4() {
46 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
47}
48
49void SocketTest::TestConnectWithDnsLookupIPv6() {
50 // TODO: Enable this when DNS resolution supports IPv6.
51 LOG(LS_INFO) << "Skipping IPv6 DNS test";
52 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
53}
54
55void SocketTest::TestConnectFailIPv4() {
56 ConnectFailInternal(kIPv4Loopback);
57}
58
59void SocketTest::TestConnectFailIPv6() {
60 MAYBE_SKIP_IPV6;
61 ConnectFailInternal(kIPv6Loopback);
62}
63
64void SocketTest::TestConnectWithDnsLookupFailIPv4() {
65 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
66}
67
68void SocketTest::TestConnectWithDnsLookupFailIPv6() {
69 MAYBE_SKIP_IPV6;
70 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
71}
72
73void SocketTest::TestConnectWithClosedSocketIPv4() {
74 ConnectWithClosedSocketInternal(kIPv4Loopback);
75}
76
77void SocketTest::TestConnectWithClosedSocketIPv6() {
78 MAYBE_SKIP_IPV6;
79 ConnectWithClosedSocketInternal(kIPv6Loopback);
80}
81
82void SocketTest::TestConnectWhileNotClosedIPv4() {
83 ConnectWhileNotClosedInternal(kIPv4Loopback);
84}
85
86void SocketTest::TestConnectWhileNotClosedIPv6() {
87 MAYBE_SKIP_IPV6;
88 ConnectWhileNotClosedInternal(kIPv6Loopback);
89}
90
91void SocketTest::TestServerCloseDuringConnectIPv4() {
92 ServerCloseDuringConnectInternal(kIPv4Loopback);
93}
94
95void SocketTest::TestServerCloseDuringConnectIPv6() {
96 MAYBE_SKIP_IPV6;
97 ServerCloseDuringConnectInternal(kIPv6Loopback);
98}
99
100void SocketTest::TestClientCloseDuringConnectIPv4() {
101 ClientCloseDuringConnectInternal(kIPv4Loopback);
102}
103
104void SocketTest::TestClientCloseDuringConnectIPv6() {
105 MAYBE_SKIP_IPV6;
106 ClientCloseDuringConnectInternal(kIPv6Loopback);
107}
108
109void SocketTest::TestServerCloseIPv4() {
110 ServerCloseInternal(kIPv4Loopback);
111}
112
113void SocketTest::TestServerCloseIPv6() {
114 MAYBE_SKIP_IPV6;
115 ServerCloseInternal(kIPv6Loopback);
116}
117
118void SocketTest::TestCloseInClosedCallbackIPv4() {
119 CloseInClosedCallbackInternal(kIPv4Loopback);
120}
121
122void SocketTest::TestCloseInClosedCallbackIPv6() {
123 MAYBE_SKIP_IPV6;
124 CloseInClosedCallbackInternal(kIPv6Loopback);
125}
126
127void SocketTest::TestSocketServerWaitIPv4() {
128 SocketServerWaitInternal(kIPv4Loopback);
129}
130
131void SocketTest::TestSocketServerWaitIPv6() {
132 MAYBE_SKIP_IPV6;
133 SocketServerWaitInternal(kIPv6Loopback);
134}
135
136void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800137 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000138}
139
140void SocketTest::TestTcpIPv6() {
141 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800142 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000143}
144
145void SocketTest::TestSingleFlowControlCallbackIPv4() {
146 SingleFlowControlCallbackInternal(kIPv4Loopback);
147}
148
149void SocketTest::TestSingleFlowControlCallbackIPv6() {
150 MAYBE_SKIP_IPV6;
151 SingleFlowControlCallbackInternal(kIPv6Loopback);
152}
153
154void SocketTest::TestUdpIPv4() {
155 UdpInternal(kIPv4Loopback);
156}
157
158void SocketTest::TestUdpIPv6() {
159 MAYBE_SKIP_IPV6;
160 UdpInternal(kIPv6Loopback);
161}
162
163void SocketTest::TestUdpReadyToSendIPv4() {
164#if !defined(WEBRTC_MAC)
165 // TODO(ronghuawu): Enable this test on mac/ios.
166 UdpReadyToSend(kIPv4Loopback);
167#endif
168}
169
170void SocketTest::TestUdpReadyToSendIPv6() {
171#if defined(WEBRTC_WIN)
172 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
173 MAYBE_SKIP_IPV6;
174 UdpReadyToSend(kIPv6Loopback);
175#endif
176}
177
178void SocketTest::TestGetSetOptionsIPv4() {
179 GetSetOptionsInternal(kIPv4Loopback);
180}
181
182void SocketTest::TestGetSetOptionsIPv6() {
183 MAYBE_SKIP_IPV6;
184 GetSetOptionsInternal(kIPv6Loopback);
185}
186
187// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
188// values on Windows, but an empty address of the same family on Linux/MacOS X.
189bool IsUnspecOrEmptyIP(const IPAddress& address) {
190#if !defined(WEBRTC_WIN)
191 return IPIsAny(address);
192#else
193 return address.family() == AF_UNSPEC;
194#endif
195}
196
197void SocketTest::ConnectInternal(const IPAddress& loopback) {
198 testing::StreamSink sink;
199 SocketAddress accept_addr;
200
201 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700202 std::unique_ptr<AsyncSocket> client(
203 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000204 sink.Monitor(client.get());
205 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
206 EXPECT_PRED1(IsUnspecOrEmptyIP, client->GetLocalAddress().ipaddr());
207
208 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700209 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000210 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
211 sink.Monitor(server.get());
212 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
213 EXPECT_EQ(0, server->Listen(5));
214 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
215
216 // Ensure no pending server connections, since we haven't done anything yet.
217 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
218 EXPECT_TRUE(NULL == server->Accept(&accept_addr));
219 EXPECT_TRUE(accept_addr.IsNil());
220
221 // Attempt connect to listening socket.
222 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
223 EXPECT_FALSE(client->GetLocalAddress().IsNil());
224 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
225
226 // Client is connecting, outcome not yet determined.
227 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
228 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
229 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
230
231 // Server has pending connection, accept it.
232 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700233 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000234 ASSERT_TRUE(accepted);
235 EXPECT_FALSE(accept_addr.IsNil());
236 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
237
238 // Connected from server perspective, check the addresses are correct.
239 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
240 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
241 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
242
243 // Connected from client perspective, check the addresses are correct.
244 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
245 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
246 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
247 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
248 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
249}
250
251void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
252 const std::string& host) {
253 testing::StreamSink sink;
254 SocketAddress accept_addr;
255
256 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700257 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000258 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
259 sink.Monitor(client.get());
260
261 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700262 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000263 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
264 sink.Monitor(server.get());
265 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
266 EXPECT_EQ(0, server->Listen(5));
267
268 // Attempt connect to listening socket.
269 SocketAddress dns_addr(server->GetLocalAddress());
270 dns_addr.SetIP(host);
271 EXPECT_EQ(0, client->Connect(dns_addr));
272 // TODO: Bind when doing DNS lookup.
273 //EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
274
275 // Client is connecting, outcome not yet determined.
276 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
277 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
278 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
279
280 // Server has pending connection, accept it.
281 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700282 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000283 ASSERT_TRUE(accepted);
284 EXPECT_FALSE(accept_addr.IsNil());
285 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
286
287 // Connected from server perspective, check the addresses are correct.
288 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
289 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
290 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
291
292 // Connected from client perspective, check the addresses are correct.
293 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
294 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
295 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
296 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
297 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
298}
299
300void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
301 testing::StreamSink sink;
302 SocketAddress accept_addr;
303
304 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700305 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000306 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
307 sink.Monitor(client.get());
308
309 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700310 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000311 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
312 sink.Monitor(server.get());
313 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
314
315 // Attempt connect to a non-existent socket.
316 // We don't connect to the server socket created above, since on
317 // MacOS it takes about 75 seconds to get back an error!
318 SocketAddress bogus_addr(loopback, 65535);
319 EXPECT_EQ(0, client->Connect(bogus_addr));
320
321 // Wait for connection to fail (ECONNREFUSED).
322 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
323 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
324 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
325 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
326
327 // Should be no pending server connections.
328 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
329 EXPECT_TRUE(NULL == server->Accept(&accept_addr));
330 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
331}
332
333void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
334 testing::StreamSink sink;
335 SocketAddress accept_addr;
336
337 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700338 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000339 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
340 sink.Monitor(client.get());
341
342 // Create server, but don't listen yet.
jbauch555604a2016-04-26 03:13:22 -0700343 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000344 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
345 sink.Monitor(server.get());
346 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
347
348 // Attempt connect to a non-existent host.
349 // We don't connect to the server socket created above, since on
350 // MacOS it takes about 75 seconds to get back an error!
351 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
352 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
353
354 // Wait for connection to fail (EHOSTNOTFOUND).
355 bool dns_lookup_finished = false;
356 WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
357 dns_lookup_finished);
358 if (!dns_lookup_finished) {
359 LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
360 << "seconds.";
361 return;
362 }
363
364 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
365 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
366 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
367 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
368 // Should be no pending server connections.
369 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
370 EXPECT_TRUE(NULL == server->Accept(&accept_addr));
371 EXPECT_TRUE(accept_addr.IsNil());
372}
373
374void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
375 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700376 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000377 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
378 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
379 EXPECT_EQ(0, server->Listen(5));
380
381 // Create a client and put in to CS_CLOSED state.
jbauch555604a2016-04-26 03:13:22 -0700382 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000383 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
384 EXPECT_EQ(0, client->Close());
385 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
386
387 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
388 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
389 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
390}
391
392void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
393 // Create server and listen.
394 testing::StreamSink sink;
jbauch555604a2016-04-26 03:13:22 -0700395 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000396 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
397 sink.Monitor(server.get());
398 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
399 EXPECT_EQ(0, server->Listen(5));
400 // Create client, connect.
jbauch555604a2016-04-26 03:13:22 -0700401 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000402 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
403 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
404 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
405 // Try to connect again. Should fail, but not interfere with original attempt.
406 EXPECT_EQ(SOCKET_ERROR,
407 client->Connect(SocketAddress(server->GetLocalAddress())));
408
409 // Accept the original connection.
410 SocketAddress accept_addr;
411 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700412 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000413 ASSERT_TRUE(accepted);
414 EXPECT_FALSE(accept_addr.IsNil());
415
416 // Check the states and addresses.
417 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
418 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
419 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
420 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
421 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
422 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
423
424 // Try to connect again, to an unresolved hostname.
425 // Shouldn't break anything.
426 EXPECT_EQ(SOCKET_ERROR,
427 client->Connect(SocketAddress("localhost",
428 server->GetLocalAddress().port())));
429 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
430 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
431 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
432 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
433}
434
435void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
436 testing::StreamSink sink;
437
438 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700439 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000440 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
441 sink.Monitor(client.get());
442
443 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700444 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000445 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
446 sink.Monitor(server.get());
447 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
448 EXPECT_EQ(0, server->Listen(5));
449
450 // Attempt connect to listening socket.
451 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
452
453 // Close down the server while the socket is in the accept queue.
454 EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
455 server->Close();
456
457 // This should fail the connection for the client. Clean up.
458 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
459 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
460 client->Close();
461}
462
463void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
464 testing::StreamSink sink;
465 SocketAddress accept_addr;
466
467 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700468 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000469 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
470 sink.Monitor(client.get());
471
472 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700473 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000474 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
475 sink.Monitor(server.get());
476 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
477 EXPECT_EQ(0, server->Listen(5));
478
479 // Attempt connect to listening socket.
480 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
481
482 // Close down the client while the socket is in the accept queue.
483 EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
484 client->Close();
485
486 // The connection should still be able to be accepted.
jbauch555604a2016-04-26 03:13:22 -0700487 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000488 ASSERT_TRUE(accepted);
489 sink.Monitor(accepted.get());
490 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
491
492 // The accepted socket should then close (possibly with err, timing-related)
493 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
494 EXPECT_TRUE(sink.Check(accepted.get(), testing::SSE_CLOSE) ||
495 sink.Check(accepted.get(), testing::SSE_ERROR));
496
497 // The client should not get a close event.
498 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
499}
500
501void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
502 testing::StreamSink sink;
503 SocketAddress accept_addr;
504
505 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700506 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000507 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
508 sink.Monitor(client.get());
509
510 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700511 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000512 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
513 sink.Monitor(server.get());
514 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
515 EXPECT_EQ(0, server->Listen(5));
516
517 // Attempt connection.
518 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
519
520 // Accept connection.
521 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700522 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000523 ASSERT_TRUE(accepted);
524 sink.Monitor(accepted.get());
525
526 // Both sides are now connected.
527 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
528 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
529 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
530 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
531
532 // Send data to the client, and then close the connection.
533 EXPECT_EQ(1, accepted->Send("a", 1));
534 accepted->Close();
535 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
536
537 // Expect that the client is notified, and has not yet closed.
538 EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
539 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
540 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
541
542 // Ensure the data can be read.
543 char buffer[10];
544 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer)));
545 EXPECT_EQ('a', buffer[0]);
546
547 // Now we should close, but the remote address will remain.
548 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
549 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
550 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
551
552 // The closer should not get a close signal.
553 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_CLOSE));
554 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
555
556 // And the closee should only get a single signal.
557 Thread::Current()->ProcessMessages(0);
558 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
559
560 // Close down the client and ensure all is good.
561 client->Close();
562 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
563 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
564}
565
566class SocketCloser : public sigslot::has_slots<> {
567 public:
568 void OnClose(AsyncSocket* socket, int error) {
569 socket->Close(); // Deleting here would blow up the vector of handlers
570 // for the socket's signal.
571 }
572};
573
574void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
575 testing::StreamSink sink;
576 SocketCloser closer;
577 SocketAddress accept_addr;
578
579 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700580 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000581 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
582 sink.Monitor(client.get());
583 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
584
585 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700586 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000587 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
588 sink.Monitor(server.get());
589 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
590 EXPECT_EQ(0, server->Listen(5));
591
592 // Attempt connection.
593 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
594
595 // Accept connection.
596 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700597 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000598 ASSERT_TRUE(accepted);
599 sink.Monitor(accepted.get());
600
601 // Both sides are now connected.
602 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
603 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
604 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
605 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
606
607 // Send data to the client, and then close the connection.
608 accepted->Close();
609 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
610
611 // Expect that the client is notified, and has not yet closed.
612 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
613 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
614
615 // Now we should be closed and invalidated
616 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
617 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
618 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
619}
620
621class Sleeper : public MessageHandler {
622 public:
623 Sleeper() {}
624 void OnMessage(Message* msg) {
625 Thread::Current()->SleepMs(500);
626 }
627};
628
629void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
630 testing::StreamSink sink;
631 SocketAddress accept_addr;
632
633 // Create & connect server and client sockets.
jbauch555604a2016-04-26 03:13:22 -0700634 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000635 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauch555604a2016-04-26 03:13:22 -0700636 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000637 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
638 sink.Monitor(client.get());
639 sink.Monitor(server.get());
640 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
641 EXPECT_EQ(0, server->Listen(5));
642
643 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
644 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
645
jbauch555604a2016-04-26 03:13:22 -0700646 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000647 ASSERT_TRUE(accepted);
648 sink.Monitor(accepted.get());
649 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
650 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
651 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
652
653 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
654 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
655 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
656 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
657 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
658
659 // Do an i/o operation, triggering an eventual callback.
660 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
661 char buf[1024] = {0};
662
663 EXPECT_EQ(1024, client->Send(buf, 1024));
664 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
665
666 // Shouldn't signal when blocked in a thread Send, where process_io is false.
jbauch555604a2016-04-26 03:13:22 -0700667 std::unique_ptr<Thread> thread(new Thread());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000668 thread->Start();
669 Sleeper sleeper;
670 TypedMessageData<AsyncSocket*> data(client.get());
671 thread->Send(&sleeper, 0, &data);
672 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
673
674 // But should signal when process_io is true.
675 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), testing::SSE_READ)), kTimeout);
676 EXPECT_LT(0, accepted->Recv(buf, 1024));
677}
678
jbauchf2a2bf42016-02-03 16:45:32 -0800679void SocketTest::TcpInternal(const IPAddress& loopback, size_t data_size,
680 ssize_t max_send_size) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000681 testing::StreamSink sink;
682 SocketAddress accept_addr;
683
jbauchf2a2bf42016-02-03 16:45:32 -0800684 // Create receiving client.
jbauch555604a2016-04-26 03:13:22 -0700685 std::unique_ptr<AsyncSocket> receiver(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000686 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800687 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000688
689 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700690 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000691 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
692 sink.Monitor(server.get());
693 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
694 EXPECT_EQ(0, server->Listen(5));
695
696 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800697 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000698
jbauchf2a2bf42016-02-03 16:45:32 -0800699 // Accept connection which will be used for sending.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000700 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700701 std::unique_ptr<AsyncSocket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800702 ASSERT_TRUE(sender);
703 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000704
705 // Both sides are now connected.
jbauchf2a2bf42016-02-03 16:45:32 -0800706 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, receiver->GetState(), kTimeout);
707 EXPECT_TRUE(sink.Check(receiver.get(), testing::SSE_OPEN));
708 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
709 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
710
711 // Create test data.
712 rtc::Buffer send_buffer(0, data_size);
713 rtc::Buffer recv_buffer(0, data_size);
714 for (size_t i = 0; i < data_size; ++i) {
715 char ch = static_cast<char>(i % 256);
716 send_buffer.AppendData(&ch, sizeof(ch));
717 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000718
719 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800720 size_t sent_size = 0;
721 bool writable = true;
722 bool send_called = false;
723 bool readable = false;
724 bool recv_called = false;
725 while (recv_buffer.size() < send_buffer.size()) {
726 // Send as much as we can while we're cleared to send.
727 while (writable && sent_size < send_buffer.size()) {
728 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
729 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
730 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000731 // The first Send() after connecting or getting writability should
732 // succeed and send some data.
733 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800734 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000735 }
736 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800737 EXPECT_LE(sent, unsent_size);
738 sent_size += sent;
739 if (max_send_size >= 0) {
740 EXPECT_LE(static_cast<ssize_t>(sent), max_send_size);
741 if (sent < unsent_size) {
742 // If max_send_size is limiting the amount to send per call such
743 // that the sent amount is less than the unsent amount, we simulate
744 // that the socket is no longer writable.
745 writable = false;
746 }
747 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000748 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800749 ASSERT_TRUE(sender->IsBlocking());
750 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000751 }
752 }
753
754 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800755 while (recv_buffer.size() < sent_size) {
756 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000757 // Wait until data is available.
jbauchf2a2bf42016-02-03 16:45:32 -0800758 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), testing::SSE_READ),
759 kTimeout);
760 readable = true;
761 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000762 }
763
764 // Receive as much as we can get in a single recv call.
jbauchf2a2bf42016-02-03 16:45:32 -0800765 char recved_data[data_size];
766 int recved_size = receiver->Recv(recved_data, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000767
jbauchf2a2bf42016-02-03 16:45:32 -0800768 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000769 // The first Recv() after getting readability should succeed and receive
770 // some data.
771 // TODO: The following line is disabled due to flakey pulse
772 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800773 // EXPECT_GT(recved_size, 0);
774 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000775 }
jbauchf2a2bf42016-02-03 16:45:32 -0800776 if (recved_size >= 0) {
777 EXPECT_LE(static_cast<size_t>(recved_size),
778 sent_size - recv_buffer.size());
779 recv_buffer.AppendData(recved_data, recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000780 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800781 ASSERT_TRUE(receiver->IsBlocking());
782 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000783 }
784 }
785
jbauchf2a2bf42016-02-03 16:45:32 -0800786 // Once all that we've sent has been received, expect to be able to send
787 // again.
788 if (!writable) {
789 EXPECT_TRUE_WAIT(sink.Check(sender.get(), testing::SSE_WRITE),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000790 kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800791 writable = true;
792 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000793 }
794 }
795
796 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800797 EXPECT_EQ(data_size, sent_size);
798 EXPECT_EQ(data_size, recv_buffer.size());
799 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000800
801 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800802 sender->Close();
803 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, receiver->GetState(), kTimeout);
804 EXPECT_TRUE(sink.Check(receiver.get(), testing::SSE_CLOSE));
805 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000806}
807
808void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
809 testing::StreamSink sink;
810 SocketAddress accept_addr;
811
812 // Create client.
jbauch555604a2016-04-26 03:13:22 -0700813 std::unique_ptr<AsyncSocket> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000814 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
815 sink.Monitor(client.get());
816
817 // Create server and listen.
jbauch555604a2016-04-26 03:13:22 -0700818 std::unique_ptr<AsyncSocket> server(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000819 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
820 sink.Monitor(server.get());
821 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
822 EXPECT_EQ(0, server->Listen(5));
823
824 // Attempt connection.
825 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
826
827 // Accept connection.
828 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauch555604a2016-04-26 03:13:22 -0700829 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000830 ASSERT_TRUE(accepted);
831 sink.Monitor(accepted.get());
832
833 // Both sides are now connected.
834 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
835 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
836 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
837 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
838
839 // Expect a writable callback from the connect.
840 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
841
842 // Fill the socket buffer.
843 char buf[1024 * 16] = {0};
844 int sends = 0;
tfarina5237aaf2015-11-10 23:44:30 -0800845 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000846 EXPECT_TRUE(accepted->IsBlocking());
847
848 // Wait until data is available.
849 EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
850
851 // Pull data.
852 for (int i = 0; i < sends; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800853 client->Recv(buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000854 }
855
856 // Expect at least one additional writable callback.
857 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
858
859 // Adding data in response to the writeable callback shouldn't cause infinite
860 // callbacks.
861 int extras = 0;
862 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800863 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000864 rtc::Thread::Current()->ProcessMessages(1);
865 if (sink.Check(accepted.get(), testing::SSE_WRITE)) {
866 extras++;
867 }
868 }
869 EXPECT_LT(extras, 2);
870
871 // Close down.
872 accepted->Close();
873 client->Close();
874}
875
876void SocketTest::UdpInternal(const IPAddress& loopback) {
877 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
878 // Test basic bind and connect behavior.
879 AsyncSocket* socket =
880 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
881 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
882 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
883 SocketAddress addr1 = socket->GetLocalAddress();
884 EXPECT_EQ(0, socket->Connect(addr1));
885 EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
886 socket->Close();
887 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
888 delete socket;
889
890 // Test send/receive behavior.
jbauch555604a2016-04-26 03:13:22 -0700891 std::unique_ptr<TestClient> client1(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000892 new TestClient(AsyncUDPSocket::Create(ss_, addr1)));
jbauch555604a2016-04-26 03:13:22 -0700893 std::unique_ptr<TestClient> client2(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000894 new TestClient(AsyncUDPSocket::Create(ss_, empty)));
895
896 SocketAddress addr2;
897 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
898 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
899
900 SocketAddress addr3;
901 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
902 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
903 EXPECT_EQ(addr3, addr1);
904 // TODO: figure out what the intent is here
905 for (int i = 0; i < 10; ++i) {
906 client2.reset(new TestClient(AsyncUDPSocket::Create(ss_, empty)));
907
908 SocketAddress addr4;
909 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
910 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
911 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
912
913 SocketAddress addr5;
914 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
915 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
916 EXPECT_EQ(addr5, addr1);
917
918 addr2 = addr4;
919 }
920}
921
922void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
923 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
924 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
925 // documentation.
926 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
927 std::string dest = (loopback.family() == AF_INET6) ?
928 "2001:db8::1" : "192.0.2.0";
929 SocketAddress test_addr(dest, 2345);
930
931 // Test send
jbauch555604a2016-04-26 03:13:22 -0700932 std::unique_ptr<TestClient> client(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000933 new TestClient(AsyncUDPSocket::Create(ss_, empty)));
934 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -0700935 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000936 // Init the test packet just to avoid memcheck warning.
937 memset(test_packet.get(), 0, test_packet_size);
938 // Set the send buffer size to the same size as the test packet to have a
939 // better chance to get EWOULDBLOCK.
940 int send_buffer_size = test_packet_size;
941#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
942 send_buffer_size /= 2;
943#endif
944 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
945
946 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200947 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000948 int sent_packet_num = 0;
949 int expected_error = EWOULDBLOCK;
950 while (start_ms + kTimeout > Time()) {
951 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
952 ++sent_packet_num;
953 if (ret != test_packet_size) {
954 error = client->GetError();
955 if (error == expected_error) {
956 LOG(LS_INFO) << "Got expected error code after sending "
957 << sent_packet_num << " packets.";
958 break;
959 }
960 }
961 }
962 EXPECT_EQ(expected_error, error);
963 EXPECT_FALSE(client->ready_to_send());
964 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
965 LOG(LS_INFO) << "Got SignalReadyToSend";
966}
967
968void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
jbauch555604a2016-04-26 03:13:22 -0700969 std::unique_ptr<AsyncSocket> socket(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000970 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
971 socket->Bind(SocketAddress(loopback, 0));
972
973 // Check SNDBUF/RCVBUF.
974 const int desired_size = 12345;
975#if defined(WEBRTC_LINUX)
976 // Yes, really. It's in the kernel source.
977 const int expected_size = desired_size * 2;
978#else // !WEBRTC_LINUX
979 const int expected_size = desired_size;
980#endif // !WEBRTC_LINUX
981 int recv_size = 0;
982 int send_size = 0;
983 // get the initial sizes
984 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
985 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
986 // set our desired sizes
987 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
988 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
989 // get the sizes again
990 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
991 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
992 // make sure they are right
993 ASSERT_EQ(expected_size, recv_size);
994 ASSERT_EQ(expected_size, send_size);
995
996 // Check that we can't set NODELAY on a UDP socket.
997 int current_nd, desired_nd = 1;
998 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
999 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
1000
1001 // Skip the esimate MTU test for IPv6 for now.
1002 if (loopback.family() != AF_INET6) {
1003 // Try estimating MTU.
jbauch555604a2016-04-26 03:13:22 -07001004 std::unique_ptr<AsyncSocket> mtu_socket(
1005 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001006 mtu_socket->Bind(SocketAddress(loopback, 0));
Peter Boström0c4e06b2015-10-07 12:23:21 +02001007 uint16_t mtu;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001008 // should fail until we connect
1009 ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
1010 mtu_socket->Connect(SocketAddress(loopback, 0));
1011#if defined(WEBRTC_WIN)
1012 // now it should succeed
1013 ASSERT_NE(-1, mtu_socket->EstimateMTU(&mtu));
1014 ASSERT_GE(mtu, 1492); // should be at least the 1492 "plateau" on localhost
1015#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
1016 // except on WEBRTC_MAC && !WEBRTC_IOS, where it's not yet implemented
1017 ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
1018#else
1019 // and the behavior seems unpredictable on Linux,
1020 // failing on the build machine
1021 // but succeeding on my Ubiquity instance.
1022#endif
1023 }
1024}
1025
1026} // namespace rtc