blob: 720dc6ccc770cc779942f78eca1627a1b35df794 [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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "rtc_base/socket.h"
12
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <errno.h>
14#include <stdint.h>
15#include <string.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020016
jbauch555604a2016-04-26 03:13:22 -070017#include <memory>
18
Karl Wiberg918f50c2018-07-05 11:40:33 +020019#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "rtc_base/async_packet_socket.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "rtc_base/async_udp_socket.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "rtc_base/buffer.h"
24#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 16:47:49 +010025#include "rtc_base/location.h"
26#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080027#include "rtc_base/message_handler.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/net_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "rtc_base/socket_address.h"
30#include "rtc_base/socket_server.h"
Yves Gerey3e707812018-11-28 16:47:49 +010031#include "rtc_base/socket_unittest.h"
Steve Anton10542f22019-01-11 09:11:00 -080032#include "rtc_base/test_client.h"
33#include "rtc_base/test_utils.h"
Yves Gerey3e707812018-11-28 16:47:49 +010034#include "rtc_base/third_party/sigslot/sigslot.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020035#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080036#include "rtc_base/time_utils.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000037
38namespace rtc {
39
kwibergd0d81482017-04-18 03:18:22 -070040using webrtc::testing::SSE_CLOSE;
41using webrtc::testing::SSE_ERROR;
42using webrtc::testing::SSE_OPEN;
43using webrtc::testing::SSE_READ;
44using webrtc::testing::SSE_WRITE;
45using webrtc::testing::StreamSink;
46
Mirko Bonadei675513b2017-11-09 11:09:25 +010047#define MAYBE_SKIP_IPV6 \
48 if (!HasIPv6Enabled()) { \
49 RTC_LOG(LS_INFO) << "No IPv6... skipping"; \
50 return; \
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000051 }
52
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070053// Data size to be used in TcpInternal tests.
54static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000055
Steve Anton9de3aac2017-10-24 10:08:26 -070056void SocketTest::SetUp() {
57 ss_ = Thread::Current()->socketserver();
58}
59
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000060void SocketTest::TestConnectIPv4() {
61 ConnectInternal(kIPv4Loopback);
62}
63
64void SocketTest::TestConnectIPv6() {
65 MAYBE_SKIP_IPV6;
66 ConnectInternal(kIPv6Loopback);
67}
68
69void SocketTest::TestConnectWithDnsLookupIPv4() {
70 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
71}
72
73void SocketTest::TestConnectWithDnsLookupIPv6() {
74 // TODO: Enable this when DNS resolution supports IPv6.
Mirko Bonadei675513b2017-11-09 11:09:25 +010075 RTC_LOG(LS_INFO) << "Skipping IPv6 DNS test";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000076 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
77}
78
79void SocketTest::TestConnectFailIPv4() {
80 ConnectFailInternal(kIPv4Loopback);
81}
82
83void SocketTest::TestConnectFailIPv6() {
84 MAYBE_SKIP_IPV6;
85 ConnectFailInternal(kIPv6Loopback);
86}
87
88void SocketTest::TestConnectWithDnsLookupFailIPv4() {
89 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
90}
91
92void SocketTest::TestConnectWithDnsLookupFailIPv6() {
93 MAYBE_SKIP_IPV6;
94 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
95}
96
97void SocketTest::TestConnectWithClosedSocketIPv4() {
98 ConnectWithClosedSocketInternal(kIPv4Loopback);
99}
100
101void SocketTest::TestConnectWithClosedSocketIPv6() {
102 MAYBE_SKIP_IPV6;
103 ConnectWithClosedSocketInternal(kIPv6Loopback);
104}
105
106void SocketTest::TestConnectWhileNotClosedIPv4() {
107 ConnectWhileNotClosedInternal(kIPv4Loopback);
108}
109
110void SocketTest::TestConnectWhileNotClosedIPv6() {
111 MAYBE_SKIP_IPV6;
112 ConnectWhileNotClosedInternal(kIPv6Loopback);
113}
114
115void SocketTest::TestServerCloseDuringConnectIPv4() {
116 ServerCloseDuringConnectInternal(kIPv4Loopback);
117}
118
119void SocketTest::TestServerCloseDuringConnectIPv6() {
120 MAYBE_SKIP_IPV6;
121 ServerCloseDuringConnectInternal(kIPv6Loopback);
122}
123
124void SocketTest::TestClientCloseDuringConnectIPv4() {
125 ClientCloseDuringConnectInternal(kIPv4Loopback);
126}
127
128void SocketTest::TestClientCloseDuringConnectIPv6() {
129 MAYBE_SKIP_IPV6;
130 ClientCloseDuringConnectInternal(kIPv6Loopback);
131}
132
133void SocketTest::TestServerCloseIPv4() {
134 ServerCloseInternal(kIPv4Loopback);
135}
136
137void SocketTest::TestServerCloseIPv6() {
138 MAYBE_SKIP_IPV6;
139 ServerCloseInternal(kIPv6Loopback);
140}
141
142void SocketTest::TestCloseInClosedCallbackIPv4() {
143 CloseInClosedCallbackInternal(kIPv4Loopback);
144}
145
146void SocketTest::TestCloseInClosedCallbackIPv6() {
147 MAYBE_SKIP_IPV6;
148 CloseInClosedCallbackInternal(kIPv6Loopback);
149}
150
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000151void SocketTest::TestDeleteInReadCallbackIPv4() {
152 DeleteInReadCallbackInternal(kIPv4Loopback);
153}
154
155void SocketTest::TestDeleteInReadCallbackIPv6() {
156 MAYBE_SKIP_IPV6;
157 DeleteInReadCallbackInternal(kIPv6Loopback);
158}
159
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000160void SocketTest::TestSocketServerWaitIPv4() {
161 SocketServerWaitInternal(kIPv4Loopback);
162}
163
164void SocketTest::TestSocketServerWaitIPv6() {
165 MAYBE_SKIP_IPV6;
166 SocketServerWaitInternal(kIPv6Loopback);
167}
168
169void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800170 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000171}
172
173void SocketTest::TestTcpIPv6() {
174 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800175 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000176}
177
178void SocketTest::TestSingleFlowControlCallbackIPv4() {
179 SingleFlowControlCallbackInternal(kIPv4Loopback);
180}
181
182void SocketTest::TestSingleFlowControlCallbackIPv6() {
183 MAYBE_SKIP_IPV6;
184 SingleFlowControlCallbackInternal(kIPv6Loopback);
185}
186
187void SocketTest::TestUdpIPv4() {
188 UdpInternal(kIPv4Loopback);
189}
190
191void SocketTest::TestUdpIPv6() {
192 MAYBE_SKIP_IPV6;
193 UdpInternal(kIPv6Loopback);
194}
195
196void SocketTest::TestUdpReadyToSendIPv4() {
197#if !defined(WEBRTC_MAC)
198 // TODO(ronghuawu): Enable this test on mac/ios.
199 UdpReadyToSend(kIPv4Loopback);
200#endif
201}
202
203void SocketTest::TestUdpReadyToSendIPv6() {
204#if defined(WEBRTC_WIN)
205 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
206 MAYBE_SKIP_IPV6;
207 UdpReadyToSend(kIPv6Loopback);
208#endif
209}
210
211void SocketTest::TestGetSetOptionsIPv4() {
212 GetSetOptionsInternal(kIPv4Loopback);
213}
214
215void SocketTest::TestGetSetOptionsIPv6() {
216 MAYBE_SKIP_IPV6;
217 GetSetOptionsInternal(kIPv6Loopback);
218}
219
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700220void SocketTest::TestSocketRecvTimestampIPv4() {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200221 SocketRecvTimestamp(kIPv4Loopback);
222}
223
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700224void SocketTest::TestSocketRecvTimestampIPv6() {
225 MAYBE_SKIP_IPV6;
226 SocketRecvTimestamp(kIPv6Loopback);
227}
228
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000229// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
230// values on Windows, but an empty address of the same family on Linux/MacOS X.
231bool IsUnspecOrEmptyIP(const IPAddress& address) {
232#if !defined(WEBRTC_WIN)
233 return IPIsAny(address);
234#else
235 return address.family() == AF_UNSPEC;
236#endif
237}
238
239void SocketTest::ConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700240 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000241 SocketAddress accept_addr;
242
243 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200244 std::unique_ptr<Socket> client(
245 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000246 sink.Monitor(client.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200247 EXPECT_EQ(Socket::CS_CLOSED, client->GetState());
Jonas Olssonabbe8412018-04-03 13:40:05 +0200248 EXPECT_TRUE(IsUnspecOrEmptyIP(client->GetLocalAddress().ipaddr()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000249
250 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200251 std::unique_ptr<Socket> server(
252 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000253 sink.Monitor(server.get());
254 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
255 EXPECT_EQ(0, server->Listen(5));
Niels Möllerd0b88792021-08-12 10:32:30 +0200256 EXPECT_EQ(Socket::CS_CONNECTING, server->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000257
258 // Ensure no pending server connections, since we haven't done anything yet.
kwibergd0d81482017-04-18 03:18:22 -0700259 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800260 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000261 EXPECT_TRUE(accept_addr.IsNil());
262
263 // Attempt connect to listening socket.
264 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
265 EXPECT_FALSE(client->GetLocalAddress().IsNil());
266 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
267
268 // Client is connecting, outcome not yet determined.
Niels Möllerd0b88792021-08-12 10:32:30 +0200269 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700270 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
271 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000272
273 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700274 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200275 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000276 ASSERT_TRUE(accepted);
277 EXPECT_FALSE(accept_addr.IsNil());
278 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
279
280 // Connected from server perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200281 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000282 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
283 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
284
285 // Connected from client perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200286 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700287 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
288 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000289 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
290 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
291}
292
293void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
294 const std::string& host) {
kwibergd0d81482017-04-18 03:18:22 -0700295 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000296 SocketAddress accept_addr;
297
298 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200299 std::unique_ptr<Socket> client(
300 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000301 sink.Monitor(client.get());
302
303 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200304 std::unique_ptr<Socket> server(
305 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000306 sink.Monitor(server.get());
307 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
308 EXPECT_EQ(0, server->Listen(5));
309
310 // Attempt connect to listening socket.
311 SocketAddress dns_addr(server->GetLocalAddress());
312 dns_addr.SetIP(host);
313 EXPECT_EQ(0, client->Connect(dns_addr));
314 // TODO: Bind when doing DNS lookup.
Yves Gerey665174f2018-06-19 15:03:05 +0200315 // EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000316
317 // Client is connecting, outcome not yet determined.
Niels Möllerd0b88792021-08-12 10:32:30 +0200318 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700319 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
320 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000321
322 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700323 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200324 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000325 ASSERT_TRUE(accepted);
326 EXPECT_FALSE(accept_addr.IsNil());
327 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
328
329 // Connected from server perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200330 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000331 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
332 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
333
334 // Connected from client perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200335 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700336 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
337 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000338 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
339 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
340}
341
342void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700343 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000344 SocketAddress accept_addr;
345
346 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200347 std::unique_ptr<Socket> client(
348 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000349 sink.Monitor(client.get());
350
351 // Create server, but don't listen yet.
Niels Möllerd0b88792021-08-12 10:32:30 +0200352 std::unique_ptr<Socket> server(
353 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000354 sink.Monitor(server.get());
355 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
356
357 // Attempt connect to a non-existent socket.
358 // We don't connect to the server socket created above, since on
359 // MacOS it takes about 75 seconds to get back an error!
360 SocketAddress bogus_addr(loopback, 65535);
361 EXPECT_EQ(0, client->Connect(bogus_addr));
362
363 // Wait for connection to fail (ECONNREFUSED).
Niels Möllerd0b88792021-08-12 10:32:30 +0200364 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700365 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
366 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000367 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
368
369 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700370 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800371 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000372 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
373}
374
375void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700376 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000377 SocketAddress accept_addr;
378
379 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200380 std::unique_ptr<Socket> client(
381 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000382 sink.Monitor(client.get());
383
384 // Create server, but don't listen yet.
Niels Möllerd0b88792021-08-12 10:32:30 +0200385 std::unique_ptr<Socket> server(
386 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000387 sink.Monitor(server.get());
388 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
389
390 // Attempt connect to a non-existent host.
391 // We don't connect to the server socket created above, since on
392 // MacOS it takes about 75 seconds to get back an error!
393 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
394 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
395
396 // Wait for connection to fail (EHOSTNOTFOUND).
397 bool dns_lookup_finished = false;
Niels Möllerd0b88792021-08-12 10:32:30 +0200398 WAIT_(client->GetState() == Socket::CS_CLOSED, kTimeout, dns_lookup_finished);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000399 if (!dns_lookup_finished) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100400 RTC_LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
Jonas Olssonb2b20312020-01-14 12:11:31 +0100401 "seconds.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000402 return;
403 }
404
Niels Möllerd0b88792021-08-12 10:32:30 +0200405 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700406 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
407 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000408 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
409 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700410 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800411 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000412 EXPECT_TRUE(accept_addr.IsNil());
413}
414
415void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
416 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200417 std::unique_ptr<Socket> server(
418 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000419 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
420 EXPECT_EQ(0, server->Listen(5));
421
422 // Create a client and put in to CS_CLOSED state.
Niels Möllerd0b88792021-08-12 10:32:30 +0200423 std::unique_ptr<Socket> client(
424 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000425 EXPECT_EQ(0, client->Close());
Niels Möllerd0b88792021-08-12 10:32:30 +0200426 EXPECT_EQ(Socket::CS_CLOSED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000427
428 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
429 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200430 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000431}
432
433void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
434 // Create server and listen.
kwibergd0d81482017-04-18 03:18:22 -0700435 StreamSink sink;
Niels Möllerd0b88792021-08-12 10:32:30 +0200436 std::unique_ptr<Socket> server(
437 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000438 sink.Monitor(server.get());
439 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
440 EXPECT_EQ(0, server->Listen(5));
441 // Create client, connect.
Niels Möllerd0b88792021-08-12 10:32:30 +0200442 std::unique_ptr<Socket> client(
443 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000444 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200445 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000446 // Try to connect again. Should fail, but not interfere with original attempt.
447 EXPECT_EQ(SOCKET_ERROR,
448 client->Connect(SocketAddress(server->GetLocalAddress())));
449
450 // Accept the original connection.
451 SocketAddress accept_addr;
kwibergd0d81482017-04-18 03:18:22 -0700452 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200453 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000454 ASSERT_TRUE(accepted);
455 EXPECT_FALSE(accept_addr.IsNil());
456
457 // Check the states and addresses.
Niels Möllerd0b88792021-08-12 10:32:30 +0200458 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000459 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
460 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
Niels Möllerd0b88792021-08-12 10:32:30 +0200461 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000462 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
463 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
464
465 // Try to connect again, to an unresolved hostname.
466 // Shouldn't break anything.
Yves Gerey665174f2018-06-19 15:03:05 +0200467 EXPECT_EQ(SOCKET_ERROR, client->Connect(SocketAddress(
468 "localhost", server->GetLocalAddress().port())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200469 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
470 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000471 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
472 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
473}
474
475void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700476 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000477
478 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200479 std::unique_ptr<Socket> client(
480 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000481 sink.Monitor(client.get());
482
483 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200484 std::unique_ptr<Socket> server(
485 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000486 sink.Monitor(server.get());
487 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
488 EXPECT_EQ(0, server->Listen(5));
489
490 // Attempt connect to listening socket.
491 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
492
493 // Close down the server while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700494 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000495 server->Close();
496
497 // This should fail the connection for the client. Clean up.
Niels Möllerd0b88792021-08-12 10:32:30 +0200498 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700499 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000500 client->Close();
501}
502
503void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700504 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000505 SocketAddress accept_addr;
506
507 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200508 std::unique_ptr<Socket> client(
509 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000510 sink.Monitor(client.get());
511
512 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200513 std::unique_ptr<Socket> server(
514 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000515 sink.Monitor(server.get());
516 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
517 EXPECT_EQ(0, server->Listen(5));
518
519 // Attempt connect to listening socket.
520 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
521
522 // Close down the client while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700523 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000524 client->Close();
525
526 // The connection should still be able to be accepted.
Niels Möllerd0b88792021-08-12 10:32:30 +0200527 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000528 ASSERT_TRUE(accepted);
529 sink.Monitor(accepted.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200530 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000531
532 // The accepted socket should then close (possibly with err, timing-related)
Niels Möllerd0b88792021-08-12 10:32:30 +0200533 EXPECT_EQ_WAIT(Socket::CS_CLOSED, accepted->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700534 EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE) ||
535 sink.Check(accepted.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000536
537 // The client should not get a close event.
kwibergd0d81482017-04-18 03:18:22 -0700538 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000539}
540
541void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700542 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000543 SocketAddress accept_addr;
544
545 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200546 std::unique_ptr<Socket> client(
547 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000548 sink.Monitor(client.get());
549
550 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200551 std::unique_ptr<Socket> server(
552 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000553 sink.Monitor(server.get());
554 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
555 EXPECT_EQ(0, server->Listen(5));
556
557 // Attempt connection.
558 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
559
560 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700561 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200562 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000563 ASSERT_TRUE(accepted);
564 sink.Monitor(accepted.get());
565
566 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200567 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700568 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000569 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
570 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
571
572 // Send data to the client, and then close the connection.
573 EXPECT_EQ(1, accepted->Send("a", 1));
574 accepted->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200575 EXPECT_EQ(Socket::CS_CLOSED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000576
577 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700578 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
579 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
Niels Möllerd0b88792021-08-12 10:32:30 +0200580 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000581
582 // Ensure the data can be read.
583 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200584 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000585 EXPECT_EQ('a', buffer[0]);
586
587 // Now we should close, but the remote address will remain.
Niels Möllerd0b88792021-08-12 10:32:30 +0200588 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700589 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000590 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
591
592 // The closer should not get a close signal.
kwibergd0d81482017-04-18 03:18:22 -0700593 EXPECT_FALSE(sink.Check(accepted.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000594 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
595
596 // And the closee should only get a single signal.
597 Thread::Current()->ProcessMessages(0);
kwibergd0d81482017-04-18 03:18:22 -0700598 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000599
600 // Close down the client and ensure all is good.
601 client->Close();
kwibergd0d81482017-04-18 03:18:22 -0700602 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000603 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
604}
605
606class SocketCloser : public sigslot::has_slots<> {
607 public:
Niels Möllerd0b88792021-08-12 10:32:30 +0200608 void OnClose(Socket* socket, int error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000609 socket->Close(); // Deleting here would blow up the vector of handlers
610 // for the socket's signal.
611 }
612};
613
614void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700615 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000616 SocketCloser closer;
617 SocketAddress accept_addr;
618
619 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200620 std::unique_ptr<Socket> client(
621 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000622 sink.Monitor(client.get());
623 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
624
625 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200626 std::unique_ptr<Socket> server(
627 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000628 sink.Monitor(server.get());
629 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
630 EXPECT_EQ(0, server->Listen(5));
631
632 // Attempt connection.
633 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
634
635 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700636 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200637 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000638 ASSERT_TRUE(accepted);
639 sink.Monitor(accepted.get());
640
641 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200642 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700643 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000644 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
645 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
646
647 // Send data to the client, and then close the connection.
648 accepted->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200649 EXPECT_EQ(Socket::CS_CLOSED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000650
651 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700652 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
Niels Möllerd0b88792021-08-12 10:32:30 +0200653 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000654
655 // Now we should be closed and invalidated
Niels Möllerd0b88792021-08-12 10:32:30 +0200656 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700657 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000658 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
659}
660
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000661// Helper class specifically for the test below.
662class SocketDeleter : public sigslot::has_slots<> {
663 public:
Niels Möllerd0b88792021-08-12 10:32:30 +0200664 explicit SocketDeleter(std::unique_ptr<Socket> socket)
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000665 : socket_(std::move(socket)) {}
666
Niels Möllerd0b88792021-08-12 10:32:30 +0200667 void Delete(Socket* other) { socket_.reset(); }
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000668
669 bool deleted() const { return socket_ == nullptr; }
670
671 private:
Niels Möllerd0b88792021-08-12 10:32:30 +0200672 std::unique_ptr<Socket> socket_;
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000673};
674
675// Tested deleting a socket within another socket's read callback. A previous
676// iteration of the select loop failed in this situation, if both sockets
677// became readable at the same time.
678void SocketTest::DeleteInReadCallbackInternal(const IPAddress& loopback) {
Niels Möllerd0b88792021-08-12 10:32:30 +0200679 std::unique_ptr<Socket> socket1(
680 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
681 std::unique_ptr<Socket> socket2(
682 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000683 EXPECT_EQ(0, socket1->Bind(SocketAddress(loopback, 0)));
684 EXPECT_EQ(0, socket2->Bind(SocketAddress(loopback, 0)));
685 EXPECT_EQ(3, socket1->SendTo("foo", 3, socket1->GetLocalAddress()));
686 EXPECT_EQ(3, socket2->SendTo("bar", 3, socket1->GetLocalAddress()));
687 // Sleep a while to ensure sends are both completed at the same time.
688 Thread::SleepMs(1000);
689
690 // Configure the helper class to delete socket 2 when socket 1 has a read
691 // event.
692 SocketDeleter deleter(std::move(socket2));
693 socket1->SignalReadEvent.connect(&deleter, &SocketDeleter::Delete);
694 EXPECT_TRUE_WAIT(deleter.deleted(), kTimeout);
695}
696
Tomas Gunnarssonabdb4702020-09-05 18:43:36 +0200697class Sleeper : public MessageHandlerAutoCleanup {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000698 public:
Steve Anton9de3aac2017-10-24 10:08:26 -0700699 void OnMessage(Message* msg) override { Thread::Current()->SleepMs(500); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000700};
701
702void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700703 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000704 SocketAddress accept_addr;
705
706 // Create & connect server and client sockets.
Niels Möllerd0b88792021-08-12 10:32:30 +0200707 std::unique_ptr<Socket> client(
708 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
709 std::unique_ptr<Socket> server(
710 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000711 sink.Monitor(client.get());
712 sink.Monitor(server.get());
713 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
714 EXPECT_EQ(0, server->Listen(5));
715
716 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
kwibergd0d81482017-04-18 03:18:22 -0700717 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000718
Niels Möllerd0b88792021-08-12 10:32:30 +0200719 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000720 ASSERT_TRUE(accepted);
721 sink.Monitor(accepted.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200722 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000723 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
724 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
725
Niels Möllerd0b88792021-08-12 10:32:30 +0200726 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700727 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
728 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000729 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
730 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
731
732 // Do an i/o operation, triggering an eventual callback.
kwibergd0d81482017-04-18 03:18:22 -0700733 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000734 char buf[1024] = {0};
735
736 EXPECT_EQ(1024, client->Send(buf, 1024));
kwibergd0d81482017-04-18 03:18:22 -0700737 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000738
739 // Shouldn't signal when blocked in a thread Send, where process_io is false.
tommie7251592017-07-14 14:44:46 -0700740 std::unique_ptr<Thread> thread(Thread::CreateWithSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000741 thread->Start();
742 Sleeper sleeper;
Niels Möllerd0b88792021-08-12 10:32:30 +0200743 TypedMessageData<Socket*> data(client.get());
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700744 thread->Send(RTC_FROM_HERE, &sleeper, 0, &data);
kwibergd0d81482017-04-18 03:18:22 -0700745 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000746
747 // But should signal when process_io is true.
kwibergd0d81482017-04-18 03:18:22 -0700748 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200749 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000750}
751
Yves Gerey665174f2018-06-19 15:03:05 +0200752void SocketTest::TcpInternal(const IPAddress& loopback,
753 size_t data_size,
754 ptrdiff_t max_send_size) {
kwibergd0d81482017-04-18 03:18:22 -0700755 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000756 SocketAddress accept_addr;
757
jbauchf2a2bf42016-02-03 16:45:32 -0800758 // Create receiving client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200759 std::unique_ptr<Socket> receiver(
760 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800761 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000762
763 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200764 std::unique_ptr<Socket> server(
765 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000766 sink.Monitor(server.get());
767 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
768 EXPECT_EQ(0, server->Listen(5));
769
770 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800771 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000772
jbauchf2a2bf42016-02-03 16:45:32 -0800773 // Accept connection which will be used for sending.
kwibergd0d81482017-04-18 03:18:22 -0700774 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200775 std::unique_ptr<Socket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800776 ASSERT_TRUE(sender);
777 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000778
779 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200780 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700781 EXPECT_TRUE(sink.Check(receiver.get(), SSE_OPEN));
jbauchf2a2bf42016-02-03 16:45:32 -0800782 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
783 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
784
785 // Create test data.
786 rtc::Buffer send_buffer(0, data_size);
787 rtc::Buffer recv_buffer(0, data_size);
788 for (size_t i = 0; i < data_size; ++i) {
789 char ch = static_cast<char>(i % 256);
790 send_buffer.AppendData(&ch, sizeof(ch));
791 }
danilchapb7b9dca2016-08-05 05:55:43 -0700792 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000793
794 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800795 size_t sent_size = 0;
796 bool writable = true;
797 bool send_called = false;
798 bool readable = false;
799 bool recv_called = false;
800 while (recv_buffer.size() < send_buffer.size()) {
801 // Send as much as we can while we're cleared to send.
802 while (writable && sent_size < send_buffer.size()) {
803 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
804 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
805 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000806 // The first Send() after connecting or getting writability should
807 // succeed and send some data.
808 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800809 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000810 }
811 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800812 EXPECT_LE(sent, unsent_size);
813 sent_size += sent;
814 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 05:55:43 -0700815 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-03 16:45:32 -0800816 if (sent < unsent_size) {
817 // If max_send_size is limiting the amount to send per call such
818 // that the sent amount is less than the unsent amount, we simulate
819 // that the socket is no longer writable.
820 writable = false;
821 }
822 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000823 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800824 ASSERT_TRUE(sender->IsBlocking());
825 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000826 }
827 }
828
829 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800830 while (recv_buffer.size() < sent_size) {
831 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000832 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700833 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), SSE_READ), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800834 readable = true;
835 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000836 }
837
838 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 05:55:43 -0700839 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000840
jbauchf2a2bf42016-02-03 16:45:32 -0800841 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000842 // The first Recv() after getting readability should succeed and receive
843 // some data.
844 // TODO: The following line is disabled due to flakey pulse
845 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800846 // EXPECT_GT(recved_size, 0);
847 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000848 }
jbauchf2a2bf42016-02-03 16:45:32 -0800849 if (recved_size >= 0) {
850 EXPECT_LE(static_cast<size_t>(recved_size),
Yves Gerey665174f2018-06-19 15:03:05 +0200851 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 05:55:43 -0700852 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000853 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800854 ASSERT_TRUE(receiver->IsBlocking());
855 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000856 }
857 }
858
jbauchf2a2bf42016-02-03 16:45:32 -0800859 // Once all that we've sent has been received, expect to be able to send
860 // again.
861 if (!writable) {
kwibergd0d81482017-04-18 03:18:22 -0700862 ASSERT_TRUE_WAIT(sink.Check(sender.get(), SSE_WRITE), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800863 writable = true;
864 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000865 }
866 }
867
868 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800869 EXPECT_EQ(data_size, sent_size);
870 EXPECT_EQ(data_size, recv_buffer.size());
871 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000872
873 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800874 sender->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200875 EXPECT_EQ_WAIT(Socket::CS_CLOSED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700876 EXPECT_TRUE(sink.Check(receiver.get(), SSE_CLOSE));
jbauchf2a2bf42016-02-03 16:45:32 -0800877 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000878}
879
880void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700881 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000882 SocketAddress accept_addr;
883
884 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200885 std::unique_ptr<Socket> client(
886 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000887 sink.Monitor(client.get());
888
889 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200890 std::unique_ptr<Socket> server(
891 ss_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000892 sink.Monitor(server.get());
893 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
894 EXPECT_EQ(0, server->Listen(5));
895
896 // Attempt connection.
897 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
898
899 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700900 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200901 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000902 ASSERT_TRUE(accepted);
903 sink.Monitor(accepted.get());
904
905 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200906 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700907 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000908 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
909 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
910
911 // Expect a writable callback from the connect.
kwibergd0d81482017-04-18 03:18:22 -0700912 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000913
914 // Fill the socket buffer.
915 char buf[1024 * 16] = {0};
916 int sends = 0;
Yves Gerey665174f2018-06-19 15:03:05 +0200917 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {
918 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000919 EXPECT_TRUE(accepted->IsBlocking());
920
921 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700922 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000923
924 // Pull data.
925 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200926 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000927 }
928
929 // Expect at least one additional writable callback.
kwibergd0d81482017-04-18 03:18:22 -0700930 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000931
932 // Adding data in response to the writeable callback shouldn't cause infinite
933 // callbacks.
934 int extras = 0;
935 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800936 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000937 rtc::Thread::Current()->ProcessMessages(1);
kwibergd0d81482017-04-18 03:18:22 -0700938 if (sink.Check(accepted.get(), SSE_WRITE)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000939 extras++;
940 }
941 }
942 EXPECT_LT(extras, 2);
943
944 // Close down.
945 accepted->Close();
946 client->Close();
947}
948
949void SocketTest::UdpInternal(const IPAddress& loopback) {
950 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
951 // Test basic bind and connect behavior.
Niels Möllerd0b88792021-08-12 10:32:30 +0200952 Socket* socket = ss_->CreateSocket(loopback.family(), SOCK_DGRAM);
953 EXPECT_EQ(Socket::CS_CLOSED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000954 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
955 SocketAddress addr1 = socket->GetLocalAddress();
956 EXPECT_EQ(0, socket->Connect(addr1));
Niels Möllerd0b88792021-08-12 10:32:30 +0200957 EXPECT_EQ(Socket::CS_CONNECTED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000958 socket->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200959 EXPECT_EQ(Socket::CS_CLOSED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000960 delete socket;
961
962 // Test send/receive behavior.
jbauch555604a2016-04-26 03:13:22 -0700963 std::unique_ptr<TestClient> client1(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200964 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, addr1))));
jbauch555604a2016-04-26 03:13:22 -0700965 std::unique_ptr<TestClient> client2(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200966 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000967
968 SocketAddress addr2;
969 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
970 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
971
972 SocketAddress addr3;
973 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
974 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
975 EXPECT_EQ(addr3, addr1);
976 // TODO: figure out what the intent is here
977 for (int i = 0; i < 10; ++i) {
nisse32f25052017-05-08 01:57:18 -0700978 client2.reset(
Karl Wiberg918f50c2018-07-05 11:40:33 +0200979 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000980
981 SocketAddress addr4;
982 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
983 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
984 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
985
986 SocketAddress addr5;
987 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
988 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
989 EXPECT_EQ(addr5, addr1);
990
991 addr2 = addr4;
992 }
993}
994
995void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
996 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
997 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
998 // documentation.
999 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
Yves Gerey665174f2018-06-19 15:03:05 +02001000 std::string dest =
1001 (loopback.family() == AF_INET6) ? "2001:db8::1" : "192.0.2.0";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001002 SocketAddress test_addr(dest, 2345);
1003
1004 // Test send
jbauch555604a2016-04-26 03:13:22 -07001005 std::unique_ptr<TestClient> client(
Karl Wiberg918f50c2018-07-05 11:40:33 +02001006 new TestClient(absl::WrapUnique(AsyncUDPSocket::Create(ss_, empty))));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001007 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -07001008 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001009 // Init the test packet just to avoid memcheck warning.
1010 memset(test_packet.get(), 0, test_packet_size);
1011 // Set the send buffer size to the same size as the test packet to have a
1012 // better chance to get EWOULDBLOCK.
1013 int send_buffer_size = test_packet_size;
1014#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
1015 send_buffer_size /= 2;
1016#endif
1017 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
1018
1019 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001020 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001021 int sent_packet_num = 0;
1022 int expected_error = EWOULDBLOCK;
1023 while (start_ms + kTimeout > Time()) {
1024 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
1025 ++sent_packet_num;
1026 if (ret != test_packet_size) {
1027 error = client->GetError();
1028 if (error == expected_error) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001029 RTC_LOG(LS_INFO) << "Got expected error code after sending "
1030 << sent_packet_num << " packets.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001031 break;
1032 }
1033 }
1034 }
1035 EXPECT_EQ(expected_error, error);
1036 EXPECT_FALSE(client->ready_to_send());
1037 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
Mirko Bonadei675513b2017-11-09 11:09:25 +01001038 RTC_LOG(LS_INFO) << "Got SignalReadyToSend";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001039}
1040
1041void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
Niels Möllerd0b88792021-08-12 10:32:30 +02001042 std::unique_ptr<Socket> socket(
1043 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001044 socket->Bind(SocketAddress(loopback, 0));
1045
1046 // Check SNDBUF/RCVBUF.
1047 const int desired_size = 12345;
1048#if defined(WEBRTC_LINUX)
1049 // Yes, really. It's in the kernel source.
1050 const int expected_size = desired_size * 2;
1051#else // !WEBRTC_LINUX
1052 const int expected_size = desired_size;
1053#endif // !WEBRTC_LINUX
1054 int recv_size = 0;
1055 int send_size = 0;
1056 // get the initial sizes
1057 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1058 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1059 // set our desired sizes
1060 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
1061 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
1062 // get the sizes again
1063 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1064 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1065 // make sure they are right
1066 ASSERT_EQ(expected_size, recv_size);
1067 ASSERT_EQ(expected_size, send_size);
1068
1069 // Check that we can't set NODELAY on a UDP socket.
1070 int current_nd, desired_nd = 1;
1071 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1072 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -08001073
1074#if defined(WEBRTC_POSIX)
1075 // Check DSCP.
1076 int current_dscp, desired_dscp = 1;
1077 ASSERT_NE(-1, socket->GetOption(Socket::OPT_DSCP, &current_dscp));
1078 ASSERT_NE(-1, socket->SetOption(Socket::OPT_DSCP, desired_dscp));
1079 ASSERT_NE(-1, socket->GetOption(Socket::OPT_DSCP, &current_dscp));
1080 ASSERT_EQ(desired_dscp, current_dscp);
1081#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001082}
1083
Stefan Holmer9131efd2016-05-23 18:19:26 +02001084void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
1085 std::unique_ptr<Socket> socket(
1086 ss_->CreateSocket(loopback.family(), SOCK_DGRAM));
1087 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1088 SocketAddress address = socket->GetLocalAddress();
1089
nissedeb95f32016-11-28 01:54:54 -08001090 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001091 socket->SendTo("foo", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001092 int64_t recv_timestamp_1;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001093 char buffer[3];
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001094 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1);
1095 EXPECT_GT(recv_timestamp_1, -1);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001096
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001097 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001098 Thread::SleepMs(kTimeBetweenPacketsMs);
1099
nissedeb95f32016-11-28 01:54:54 -08001100 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001101 socket->SendTo("bar", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001102 int64_t recv_timestamp_2;
1103 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2);
1104
1105 int64_t system_time_diff = send_time_2 - send_time_1;
1106 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1107 // Compare against the system time at the point of sending, because
1108 // SleepMs may not sleep for exactly the requested time.
1109 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001110}
1111
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001112} // namespace rtc