blob: d1369e2f78c1bef806e272ece186c9f60e327292 [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
11#include "webrtc/base/socket_unittest.h"
12
tfarina5237aaf2015-11-10 23:44:30 -080013#include "webrtc/base/arraysize.h"
jbauchf2a2bf42016-02-03 16:45:32 -080014#include "webrtc/base/buffer.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000015#include "webrtc/base/asyncudpsocket.h"
16#include "webrtc/base/gunit.h"
17#include "webrtc/base/nethelpers.h"
18#include "webrtc/base/socketserver.h"
19#include "webrtc/base/testclient.h"
20#include "webrtc/base/testutils.h"
21#include "webrtc/base/thread.h"
22
23namespace rtc {
24
jbauchf2a2bf42016-02-03 16:45:32 -080025// Data size to be used in TcpInternal tests.
26static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
27
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000028#define MAYBE_SKIP_IPV6 \
29 if (!HasIPv6Enabled()) { \
30 LOG(LS_INFO) << "No IPv6... skipping"; \
31 return; \
32 }
33
34
35void SocketTest::TestConnectIPv4() {
36 ConnectInternal(kIPv4Loopback);
37}
38
39void SocketTest::TestConnectIPv6() {
40 MAYBE_SKIP_IPV6;
41 ConnectInternal(kIPv6Loopback);
42}
43
44void SocketTest::TestConnectWithDnsLookupIPv4() {
45 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
46}
47
48void SocketTest::TestConnectWithDnsLookupIPv6() {
49 // TODO: Enable this when DNS resolution supports IPv6.
50 LOG(LS_INFO) << "Skipping IPv6 DNS test";
51 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
52}
53
54void SocketTest::TestConnectFailIPv4() {
55 ConnectFailInternal(kIPv4Loopback);
56}
57
58void SocketTest::TestConnectFailIPv6() {
59 MAYBE_SKIP_IPV6;
60 ConnectFailInternal(kIPv6Loopback);
61}
62
63void SocketTest::TestConnectWithDnsLookupFailIPv4() {
64 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
65}
66
67void SocketTest::TestConnectWithDnsLookupFailIPv6() {
68 MAYBE_SKIP_IPV6;
69 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
70}
71
72void SocketTest::TestConnectWithClosedSocketIPv4() {
73 ConnectWithClosedSocketInternal(kIPv4Loopback);
74}
75
76void SocketTest::TestConnectWithClosedSocketIPv6() {
77 MAYBE_SKIP_IPV6;
78 ConnectWithClosedSocketInternal(kIPv6Loopback);
79}
80
81void SocketTest::TestConnectWhileNotClosedIPv4() {
82 ConnectWhileNotClosedInternal(kIPv4Loopback);
83}
84
85void SocketTest::TestConnectWhileNotClosedIPv6() {
86 MAYBE_SKIP_IPV6;
87 ConnectWhileNotClosedInternal(kIPv6Loopback);
88}
89
90void SocketTest::TestServerCloseDuringConnectIPv4() {
91 ServerCloseDuringConnectInternal(kIPv4Loopback);
92}
93
94void SocketTest::TestServerCloseDuringConnectIPv6() {
95 MAYBE_SKIP_IPV6;
96 ServerCloseDuringConnectInternal(kIPv6Loopback);
97}
98
99void SocketTest::TestClientCloseDuringConnectIPv4() {
100 ClientCloseDuringConnectInternal(kIPv4Loopback);
101}
102
103void SocketTest::TestClientCloseDuringConnectIPv6() {
104 MAYBE_SKIP_IPV6;
105 ClientCloseDuringConnectInternal(kIPv6Loopback);
106}
107
108void SocketTest::TestServerCloseIPv4() {
109 ServerCloseInternal(kIPv4Loopback);
110}
111
112void SocketTest::TestServerCloseIPv6() {
113 MAYBE_SKIP_IPV6;
114 ServerCloseInternal(kIPv6Loopback);
115}
116
117void SocketTest::TestCloseInClosedCallbackIPv4() {
118 CloseInClosedCallbackInternal(kIPv4Loopback);
119}
120
121void SocketTest::TestCloseInClosedCallbackIPv6() {
122 MAYBE_SKIP_IPV6;
123 CloseInClosedCallbackInternal(kIPv6Loopback);
124}
125
126void SocketTest::TestSocketServerWaitIPv4() {
127 SocketServerWaitInternal(kIPv4Loopback);
128}
129
130void SocketTest::TestSocketServerWaitIPv6() {
131 MAYBE_SKIP_IPV6;
132 SocketServerWaitInternal(kIPv6Loopback);
133}
134
135void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800136 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000137}
138
139void SocketTest::TestTcpIPv6() {
140 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800141 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000142}
143
144void SocketTest::TestSingleFlowControlCallbackIPv4() {
145 SingleFlowControlCallbackInternal(kIPv4Loopback);
146}
147
148void SocketTest::TestSingleFlowControlCallbackIPv6() {
149 MAYBE_SKIP_IPV6;
150 SingleFlowControlCallbackInternal(kIPv6Loopback);
151}
152
153void SocketTest::TestUdpIPv4() {
154 UdpInternal(kIPv4Loopback);
155}
156
157void SocketTest::TestUdpIPv6() {
158 MAYBE_SKIP_IPV6;
159 UdpInternal(kIPv6Loopback);
160}
161
162void SocketTest::TestUdpReadyToSendIPv4() {
163#if !defined(WEBRTC_MAC)
164 // TODO(ronghuawu): Enable this test on mac/ios.
165 UdpReadyToSend(kIPv4Loopback);
166#endif
167}
168
169void SocketTest::TestUdpReadyToSendIPv6() {
170#if defined(WEBRTC_WIN)
171 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
172 MAYBE_SKIP_IPV6;
173 UdpReadyToSend(kIPv6Loopback);
174#endif
175}
176
177void SocketTest::TestGetSetOptionsIPv4() {
178 GetSetOptionsInternal(kIPv4Loopback);
179}
180
181void SocketTest::TestGetSetOptionsIPv6() {
182 MAYBE_SKIP_IPV6;
183 GetSetOptionsInternal(kIPv6Loopback);
184}
185
186// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
187// values on Windows, but an empty address of the same family on Linux/MacOS X.
188bool IsUnspecOrEmptyIP(const IPAddress& address) {
189#if !defined(WEBRTC_WIN)
190 return IPIsAny(address);
191#else
192 return address.family() == AF_UNSPEC;
193#endif
194}
195
196void SocketTest::ConnectInternal(const IPAddress& loopback) {
197 testing::StreamSink sink;
198 SocketAddress accept_addr;
199
200 // Create client.
201 scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(loopback.family(),
202 SOCK_STREAM));
203 sink.Monitor(client.get());
204 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
205 EXPECT_PRED1(IsUnspecOrEmptyIP, client->GetLocalAddress().ipaddr());
206
207 // Create server and listen.
208 scoped_ptr<AsyncSocket> server(
209 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
210 sink.Monitor(server.get());
211 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
212 EXPECT_EQ(0, server->Listen(5));
213 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
214
215 // Ensure no pending server connections, since we haven't done anything yet.
216 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
217 EXPECT_TRUE(NULL == server->Accept(&accept_addr));
218 EXPECT_TRUE(accept_addr.IsNil());
219
220 // Attempt connect to listening socket.
221 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
222 EXPECT_FALSE(client->GetLocalAddress().IsNil());
223 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
224
225 // Client is connecting, outcome not yet determined.
226 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
227 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
228 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
229
230 // Server has pending connection, accept it.
231 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
232 scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
233 ASSERT_TRUE(accepted);
234 EXPECT_FALSE(accept_addr.IsNil());
235 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
236
237 // Connected from server perspective, check the addresses are correct.
238 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
239 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
240 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
241
242 // Connected from client perspective, check the addresses are correct.
243 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
244 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
245 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
246 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
247 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
248}
249
250void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
251 const std::string& host) {
252 testing::StreamSink sink;
253 SocketAddress accept_addr;
254
255 // Create client.
256 scoped_ptr<AsyncSocket> client(
257 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
258 sink.Monitor(client.get());
259
260 // Create server and listen.
261 scoped_ptr<AsyncSocket> server(
262 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
263 sink.Monitor(server.get());
264 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
265 EXPECT_EQ(0, server->Listen(5));
266
267 // Attempt connect to listening socket.
268 SocketAddress dns_addr(server->GetLocalAddress());
269 dns_addr.SetIP(host);
270 EXPECT_EQ(0, client->Connect(dns_addr));
271 // TODO: Bind when doing DNS lookup.
272 //EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
273
274 // Client is connecting, outcome not yet determined.
275 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
276 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
277 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
278
279 // Server has pending connection, accept it.
280 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
281 scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
282 ASSERT_TRUE(accepted);
283 EXPECT_FALSE(accept_addr.IsNil());
284 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
285
286 // Connected from server perspective, check the addresses are correct.
287 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
288 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
289 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
290
291 // Connected from client perspective, check the addresses are correct.
292 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
293 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
294 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
295 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
296 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
297}
298
299void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
300 testing::StreamSink sink;
301 SocketAddress accept_addr;
302
303 // Create client.
304 scoped_ptr<AsyncSocket> client(
305 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
306 sink.Monitor(client.get());
307
308 // Create server, but don't listen yet.
309 scoped_ptr<AsyncSocket> server(
310 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
311 sink.Monitor(server.get());
312 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
313
314 // Attempt connect to a non-existent socket.
315 // We don't connect to the server socket created above, since on
316 // MacOS it takes about 75 seconds to get back an error!
317 SocketAddress bogus_addr(loopback, 65535);
318 EXPECT_EQ(0, client->Connect(bogus_addr));
319
320 // Wait for connection to fail (ECONNREFUSED).
321 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
322 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
323 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
324 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
325
326 // Should be no pending server connections.
327 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
328 EXPECT_TRUE(NULL == server->Accept(&accept_addr));
329 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
330}
331
332void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
333 testing::StreamSink sink;
334 SocketAddress accept_addr;
335
336 // Create client.
337 scoped_ptr<AsyncSocket> client(
338 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
339 sink.Monitor(client.get());
340
341 // Create server, but don't listen yet.
342 scoped_ptr<AsyncSocket> server(
343 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
344 sink.Monitor(server.get());
345 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
346
347 // Attempt connect to a non-existent host.
348 // We don't connect to the server socket created above, since on
349 // MacOS it takes about 75 seconds to get back an error!
350 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
351 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
352
353 // Wait for connection to fail (EHOSTNOTFOUND).
354 bool dns_lookup_finished = false;
355 WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
356 dns_lookup_finished);
357 if (!dns_lookup_finished) {
358 LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
359 << "seconds.";
360 return;
361 }
362
363 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
364 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
365 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
366 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
367 // Should be no pending server connections.
368 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
369 EXPECT_TRUE(NULL == server->Accept(&accept_addr));
370 EXPECT_TRUE(accept_addr.IsNil());
371}
372
373void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
374 // Create server and listen.
375 scoped_ptr<AsyncSocket> server(
376 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
377 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
378 EXPECT_EQ(0, server->Listen(5));
379
380 // Create a client and put in to CS_CLOSED state.
381 scoped_ptr<AsyncSocket> client(
382 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
383 EXPECT_EQ(0, client->Close());
384 EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
385
386 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
387 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
388 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
389}
390
391void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
392 // Create server and listen.
393 testing::StreamSink sink;
394 scoped_ptr<AsyncSocket> server(
395 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
396 sink.Monitor(server.get());
397 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
398 EXPECT_EQ(0, server->Listen(5));
399 // Create client, connect.
400 scoped_ptr<AsyncSocket> client(
401 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
402 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
403 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
404 // Try to connect again. Should fail, but not interfere with original attempt.
405 EXPECT_EQ(SOCKET_ERROR,
406 client->Connect(SocketAddress(server->GetLocalAddress())));
407
408 // Accept the original connection.
409 SocketAddress accept_addr;
410 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
411 scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
412 ASSERT_TRUE(accepted);
413 EXPECT_FALSE(accept_addr.IsNil());
414
415 // Check the states and addresses.
416 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
417 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
418 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
419 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
420 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
421 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
422
423 // Try to connect again, to an unresolved hostname.
424 // Shouldn't break anything.
425 EXPECT_EQ(SOCKET_ERROR,
426 client->Connect(SocketAddress("localhost",
427 server->GetLocalAddress().port())));
428 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
429 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
430 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
431 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
432}
433
434void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
435 testing::StreamSink sink;
436
437 // Create client.
438 scoped_ptr<AsyncSocket> client(
439 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
440 sink.Monitor(client.get());
441
442 // Create server and listen.
443 scoped_ptr<AsyncSocket> server(
444 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
445 sink.Monitor(server.get());
446 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
447 EXPECT_EQ(0, server->Listen(5));
448
449 // Attempt connect to listening socket.
450 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
451
452 // Close down the server while the socket is in the accept queue.
453 EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
454 server->Close();
455
456 // This should fail the connection for the client. Clean up.
457 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
458 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
459 client->Close();
460}
461
462void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
463 testing::StreamSink sink;
464 SocketAddress accept_addr;
465
466 // Create client.
467 scoped_ptr<AsyncSocket> client(
468 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
469 sink.Monitor(client.get());
470
471 // Create server and listen.
472 scoped_ptr<AsyncSocket> server(
473 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
474 sink.Monitor(server.get());
475 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
476 EXPECT_EQ(0, server->Listen(5));
477
478 // Attempt connect to listening socket.
479 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
480
481 // Close down the client while the socket is in the accept queue.
482 EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
483 client->Close();
484
485 // The connection should still be able to be accepted.
486 scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
487 ASSERT_TRUE(accepted);
488 sink.Monitor(accepted.get());
489 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
490
491 // The accepted socket should then close (possibly with err, timing-related)
492 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
493 EXPECT_TRUE(sink.Check(accepted.get(), testing::SSE_CLOSE) ||
494 sink.Check(accepted.get(), testing::SSE_ERROR));
495
496 // The client should not get a close event.
497 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
498}
499
500void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
501 testing::StreamSink sink;
502 SocketAddress accept_addr;
503
504 // Create client.
505 scoped_ptr<AsyncSocket> client(
506 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
507 sink.Monitor(client.get());
508
509 // Create server and listen.
510 scoped_ptr<AsyncSocket> server(
511 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
512 sink.Monitor(server.get());
513 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
514 EXPECT_EQ(0, server->Listen(5));
515
516 // Attempt connection.
517 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
518
519 // Accept connection.
520 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
521 scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
522 ASSERT_TRUE(accepted);
523 sink.Monitor(accepted.get());
524
525 // Both sides are now connected.
526 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
527 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
528 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
529 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
530
531 // Send data to the client, and then close the connection.
532 EXPECT_EQ(1, accepted->Send("a", 1));
533 accepted->Close();
534 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
535
536 // Expect that the client is notified, and has not yet closed.
537 EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
538 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
539 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
540
541 // Ensure the data can be read.
542 char buffer[10];
543 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer)));
544 EXPECT_EQ('a', buffer[0]);
545
546 // Now we should close, but the remote address will remain.
547 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
548 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
549 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
550
551 // The closer should not get a close signal.
552 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_CLOSE));
553 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
554
555 // And the closee should only get a single signal.
556 Thread::Current()->ProcessMessages(0);
557 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
558
559 // Close down the client and ensure all is good.
560 client->Close();
561 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
562 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
563}
564
565class SocketCloser : public sigslot::has_slots<> {
566 public:
567 void OnClose(AsyncSocket* socket, int error) {
568 socket->Close(); // Deleting here would blow up the vector of handlers
569 // for the socket's signal.
570 }
571};
572
573void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
574 testing::StreamSink sink;
575 SocketCloser closer;
576 SocketAddress accept_addr;
577
578 // Create client.
579 scoped_ptr<AsyncSocket> client(
580 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
581 sink.Monitor(client.get());
582 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
583
584 // Create server and listen.
585 scoped_ptr<AsyncSocket> server(
586 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
587 sink.Monitor(server.get());
588 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
589 EXPECT_EQ(0, server->Listen(5));
590
591 // Attempt connection.
592 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
593
594 // Accept connection.
595 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
596 scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
597 ASSERT_TRUE(accepted);
598 sink.Monitor(accepted.get());
599
600 // Both sides are now connected.
601 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
602 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
603 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
604 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
605
606 // Send data to the client, and then close the connection.
607 accepted->Close();
608 EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
609
610 // Expect that the client is notified, and has not yet closed.
611 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
612 EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
613
614 // Now we should be closed and invalidated
615 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
616 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
617 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
618}
619
620class Sleeper : public MessageHandler {
621 public:
622 Sleeper() {}
623 void OnMessage(Message* msg) {
624 Thread::Current()->SleepMs(500);
625 }
626};
627
628void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
629 testing::StreamSink sink;
630 SocketAddress accept_addr;
631
632 // Create & connect server and client sockets.
633 scoped_ptr<AsyncSocket> client(
634 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
635 scoped_ptr<AsyncSocket> server(
636 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
637 sink.Monitor(client.get());
638 sink.Monitor(server.get());
639 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
640 EXPECT_EQ(0, server->Listen(5));
641
642 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
643 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
644
645 scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
646 ASSERT_TRUE(accepted);
647 sink.Monitor(accepted.get());
648 EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
649 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
650 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
651
652 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
653 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
654 EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
655 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
656 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
657
658 // Do an i/o operation, triggering an eventual callback.
659 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
660 char buf[1024] = {0};
661
662 EXPECT_EQ(1024, client->Send(buf, 1024));
663 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
664
665 // Shouldn't signal when blocked in a thread Send, where process_io is false.
666 scoped_ptr<Thread> thread(new Thread());
667 thread->Start();
668 Sleeper sleeper;
669 TypedMessageData<AsyncSocket*> data(client.get());
670 thread->Send(&sleeper, 0, &data);
671 EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
672
673 // But should signal when process_io is true.
674 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), testing::SSE_READ)), kTimeout);
675 EXPECT_LT(0, accepted->Recv(buf, 1024));
676}
677
jbauchf2a2bf42016-02-03 16:45:32 -0800678void SocketTest::TcpInternal(const IPAddress& loopback, size_t data_size,
679 ssize_t max_send_size) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000680 testing::StreamSink sink;
681 SocketAddress accept_addr;
682
jbauchf2a2bf42016-02-03 16:45:32 -0800683 // Create receiving client.
684 scoped_ptr<AsyncSocket> receiver(
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000685 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800686 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000687
688 // Create server and listen.
689 scoped_ptr<AsyncSocket> server(
690 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
691 sink.Monitor(server.get());
692 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
693 EXPECT_EQ(0, server->Listen(5));
694
695 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800696 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000697
jbauchf2a2bf42016-02-03 16:45:32 -0800698 // Accept connection which will be used for sending.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000699 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800700 scoped_ptr<AsyncSocket> sender(server->Accept(&accept_addr));
701 ASSERT_TRUE(sender);
702 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000703
704 // Both sides are now connected.
jbauchf2a2bf42016-02-03 16:45:32 -0800705 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, receiver->GetState(), kTimeout);
706 EXPECT_TRUE(sink.Check(receiver.get(), testing::SSE_OPEN));
707 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
708 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
709
710 // Create test data.
711 rtc::Buffer send_buffer(0, data_size);
712 rtc::Buffer recv_buffer(0, data_size);
713 for (size_t i = 0; i < data_size; ++i) {
714 char ch = static_cast<char>(i % 256);
715 send_buffer.AppendData(&ch, sizeof(ch));
716 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000717
718 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800719 size_t sent_size = 0;
720 bool writable = true;
721 bool send_called = false;
722 bool readable = false;
723 bool recv_called = false;
724 while (recv_buffer.size() < send_buffer.size()) {
725 // Send as much as we can while we're cleared to send.
726 while (writable && sent_size < send_buffer.size()) {
727 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
728 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
729 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000730 // The first Send() after connecting or getting writability should
731 // succeed and send some data.
732 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800733 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000734 }
735 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800736 EXPECT_LE(sent, unsent_size);
737 sent_size += sent;
738 if (max_send_size >= 0) {
739 EXPECT_LE(static_cast<ssize_t>(sent), max_send_size);
740 if (sent < unsent_size) {
741 // If max_send_size is limiting the amount to send per call such
742 // that the sent amount is less than the unsent amount, we simulate
743 // that the socket is no longer writable.
744 writable = false;
745 }
746 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000747 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800748 ASSERT_TRUE(sender->IsBlocking());
749 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000750 }
751 }
752
753 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800754 while (recv_buffer.size() < sent_size) {
755 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000756 // Wait until data is available.
jbauchf2a2bf42016-02-03 16:45:32 -0800757 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), testing::SSE_READ),
758 kTimeout);
759 readable = true;
760 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000761 }
762
763 // Receive as much as we can get in a single recv call.
jbauchf2a2bf42016-02-03 16:45:32 -0800764 char recved_data[data_size];
765 int recved_size = receiver->Recv(recved_data, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000766
jbauchf2a2bf42016-02-03 16:45:32 -0800767 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000768 // The first Recv() after getting readability should succeed and receive
769 // some data.
770 // TODO: The following line is disabled due to flakey pulse
771 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800772 // EXPECT_GT(recved_size, 0);
773 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000774 }
jbauchf2a2bf42016-02-03 16:45:32 -0800775 if (recved_size >= 0) {
776 EXPECT_LE(static_cast<size_t>(recved_size),
777 sent_size - recv_buffer.size());
778 recv_buffer.AppendData(recved_data, recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000779 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800780 ASSERT_TRUE(receiver->IsBlocking());
781 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000782 }
783 }
784
jbauchf2a2bf42016-02-03 16:45:32 -0800785 // Once all that we've sent has been received, expect to be able to send
786 // again.
787 if (!writable) {
788 EXPECT_TRUE_WAIT(sink.Check(sender.get(), testing::SSE_WRITE),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000789 kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800790 writable = true;
791 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000792 }
793 }
794
795 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800796 EXPECT_EQ(data_size, sent_size);
797 EXPECT_EQ(data_size, recv_buffer.size());
798 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000799
800 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800801 sender->Close();
802 EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, receiver->GetState(), kTimeout);
803 EXPECT_TRUE(sink.Check(receiver.get(), testing::SSE_CLOSE));
804 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000805}
806
807void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
808 testing::StreamSink sink;
809 SocketAddress accept_addr;
810
811 // Create client.
812 scoped_ptr<AsyncSocket> client(
813 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
814 sink.Monitor(client.get());
815
816 // Create server and listen.
817 scoped_ptr<AsyncSocket> server(
818 ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
819 sink.Monitor(server.get());
820 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
821 EXPECT_EQ(0, server->Listen(5));
822
823 // Attempt connection.
824 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
825
826 // Accept connection.
827 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
828 scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
829 ASSERT_TRUE(accepted);
830 sink.Monitor(accepted.get());
831
832 // Both sides are now connected.
833 EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
834 EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
835 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
836 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
837
838 // Expect a writable callback from the connect.
839 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
840
841 // Fill the socket buffer.
842 char buf[1024 * 16] = {0};
843 int sends = 0;
tfarina5237aaf2015-11-10 23:44:30 -0800844 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000845 EXPECT_TRUE(accepted->IsBlocking());
846
847 // Wait until data is available.
848 EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
849
850 // Pull data.
851 for (int i = 0; i < sends; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800852 client->Recv(buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000853 }
854
855 // Expect at least one additional writable callback.
856 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
857
858 // Adding data in response to the writeable callback shouldn't cause infinite
859 // callbacks.
860 int extras = 0;
861 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800862 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000863 rtc::Thread::Current()->ProcessMessages(1);
864 if (sink.Check(accepted.get(), testing::SSE_WRITE)) {
865 extras++;
866 }
867 }
868 EXPECT_LT(extras, 2);
869
870 // Close down.
871 accepted->Close();
872 client->Close();
873}
874
875void SocketTest::UdpInternal(const IPAddress& loopback) {
876 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
877 // Test basic bind and connect behavior.
878 AsyncSocket* socket =
879 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
880 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
881 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
882 SocketAddress addr1 = socket->GetLocalAddress();
883 EXPECT_EQ(0, socket->Connect(addr1));
884 EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
885 socket->Close();
886 EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
887 delete socket;
888
889 // Test send/receive behavior.
890 scoped_ptr<TestClient> client1(
891 new TestClient(AsyncUDPSocket::Create(ss_, addr1)));
892 scoped_ptr<TestClient> client2(
893 new TestClient(AsyncUDPSocket::Create(ss_, empty)));
894
895 SocketAddress addr2;
896 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
897 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
898
899 SocketAddress addr3;
900 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
901 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
902 EXPECT_EQ(addr3, addr1);
903 // TODO: figure out what the intent is here
904 for (int i = 0; i < 10; ++i) {
905 client2.reset(new TestClient(AsyncUDPSocket::Create(ss_, empty)));
906
907 SocketAddress addr4;
908 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
909 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
910 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
911
912 SocketAddress addr5;
913 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
914 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
915 EXPECT_EQ(addr5, addr1);
916
917 addr2 = addr4;
918 }
919}
920
921void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
922 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
923 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
924 // documentation.
925 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
926 std::string dest = (loopback.family() == AF_INET6) ?
927 "2001:db8::1" : "192.0.2.0";
928 SocketAddress test_addr(dest, 2345);
929
930 // Test send
931 scoped_ptr<TestClient> client(
932 new TestClient(AsyncUDPSocket::Create(ss_, empty)));
933 int test_packet_size = 1200;
934 rtc::scoped_ptr<char[]> test_packet(new char[test_packet_size]);
935 // Init the test packet just to avoid memcheck warning.
936 memset(test_packet.get(), 0, test_packet_size);
937 // Set the send buffer size to the same size as the test packet to have a
938 // better chance to get EWOULDBLOCK.
939 int send_buffer_size = test_packet_size;
940#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
941 send_buffer_size /= 2;
942#endif
943 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
944
945 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200946 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000947 int sent_packet_num = 0;
948 int expected_error = EWOULDBLOCK;
949 while (start_ms + kTimeout > Time()) {
950 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
951 ++sent_packet_num;
952 if (ret != test_packet_size) {
953 error = client->GetError();
954 if (error == expected_error) {
955 LOG(LS_INFO) << "Got expected error code after sending "
956 << sent_packet_num << " packets.";
957 break;
958 }
959 }
960 }
961 EXPECT_EQ(expected_error, error);
962 EXPECT_FALSE(client->ready_to_send());
963 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
964 LOG(LS_INFO) << "Got SignalReadyToSend";
965}
966
967void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
968 rtc::scoped_ptr<AsyncSocket> socket(
969 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
970 socket->Bind(SocketAddress(loopback, 0));
971
972 // Check SNDBUF/RCVBUF.
973 const int desired_size = 12345;
974#if defined(WEBRTC_LINUX)
975 // Yes, really. It's in the kernel source.
976 const int expected_size = desired_size * 2;
977#else // !WEBRTC_LINUX
978 const int expected_size = desired_size;
979#endif // !WEBRTC_LINUX
980 int recv_size = 0;
981 int send_size = 0;
982 // get the initial sizes
983 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
984 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
985 // set our desired sizes
986 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
987 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
988 // get the sizes again
989 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
990 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
991 // make sure they are right
992 ASSERT_EQ(expected_size, recv_size);
993 ASSERT_EQ(expected_size, send_size);
994
995 // Check that we can't set NODELAY on a UDP socket.
996 int current_nd, desired_nd = 1;
997 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
998 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
999
1000 // Skip the esimate MTU test for IPv6 for now.
1001 if (loopback.family() != AF_INET6) {
1002 // Try estimating MTU.
1003 rtc::scoped_ptr<AsyncSocket>
1004 mtu_socket(
1005 ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
1006 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