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