blob: 0b9c2f2c5830da769200f4e135d97fae96955808 [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"
Ali Tofigh7fa90572022-03-17 15:47:49 +010020#include "absl/strings/string_view.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "rtc_base/async_packet_socket.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "rtc_base/async_udp_socket.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "rtc_base/buffer.h"
25#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 16:47:49 +010026#include "rtc_base/location.h"
27#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/message_handler.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "rtc_base/net_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "rtc_base/socket_address.h"
31#include "rtc_base/socket_server.h"
Yves Gerey3e707812018-11-28 16:47:49 +010032#include "rtc_base/socket_unittest.h"
Steve Anton10542f22019-01-11 09:11:00 -080033#include "rtc_base/test_client.h"
34#include "rtc_base/test_utils.h"
Yves Gerey3e707812018-11-28 16:47:49 +010035#include "rtc_base/third_party/sigslot/sigslot.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020036#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080037#include "rtc_base/time_utils.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000038
39namespace rtc {
40
kwibergd0d81482017-04-18 03:18:22 -070041using webrtc::testing::SSE_CLOSE;
42using webrtc::testing::SSE_ERROR;
43using webrtc::testing::SSE_OPEN;
44using webrtc::testing::SSE_READ;
45using webrtc::testing::SSE_WRITE;
46using webrtc::testing::StreamSink;
47
Mirko Bonadei675513b2017-11-09 11:09:25 +010048#define MAYBE_SKIP_IPV6 \
49 if (!HasIPv6Enabled()) { \
50 RTC_LOG(LS_INFO) << "No IPv6... skipping"; \
51 return; \
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000052 }
53
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070054// Data size to be used in TcpInternal tests.
55static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000056
57void SocketTest::TestConnectIPv4() {
58 ConnectInternal(kIPv4Loopback);
59}
60
61void SocketTest::TestConnectIPv6() {
62 MAYBE_SKIP_IPV6;
63 ConnectInternal(kIPv6Loopback);
64}
65
66void SocketTest::TestConnectWithDnsLookupIPv4() {
67 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
68}
69
70void SocketTest::TestConnectWithDnsLookupIPv6() {
71 // TODO: Enable this when DNS resolution supports IPv6.
Mirko Bonadei675513b2017-11-09 11:09:25 +010072 RTC_LOG(LS_INFO) << "Skipping IPv6 DNS test";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000073 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
74}
75
76void SocketTest::TestConnectFailIPv4() {
77 ConnectFailInternal(kIPv4Loopback);
78}
79
80void SocketTest::TestConnectFailIPv6() {
81 MAYBE_SKIP_IPV6;
82 ConnectFailInternal(kIPv6Loopback);
83}
84
85void SocketTest::TestConnectWithDnsLookupFailIPv4() {
86 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
87}
88
89void SocketTest::TestConnectWithDnsLookupFailIPv6() {
90 MAYBE_SKIP_IPV6;
91 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
92}
93
94void SocketTest::TestConnectWithClosedSocketIPv4() {
95 ConnectWithClosedSocketInternal(kIPv4Loopback);
96}
97
98void SocketTest::TestConnectWithClosedSocketIPv6() {
99 MAYBE_SKIP_IPV6;
100 ConnectWithClosedSocketInternal(kIPv6Loopback);
101}
102
103void SocketTest::TestConnectWhileNotClosedIPv4() {
104 ConnectWhileNotClosedInternal(kIPv4Loopback);
105}
106
107void SocketTest::TestConnectWhileNotClosedIPv6() {
108 MAYBE_SKIP_IPV6;
109 ConnectWhileNotClosedInternal(kIPv6Loopback);
110}
111
112void SocketTest::TestServerCloseDuringConnectIPv4() {
113 ServerCloseDuringConnectInternal(kIPv4Loopback);
114}
115
116void SocketTest::TestServerCloseDuringConnectIPv6() {
117 MAYBE_SKIP_IPV6;
118 ServerCloseDuringConnectInternal(kIPv6Loopback);
119}
120
121void SocketTest::TestClientCloseDuringConnectIPv4() {
122 ClientCloseDuringConnectInternal(kIPv4Loopback);
123}
124
125void SocketTest::TestClientCloseDuringConnectIPv6() {
126 MAYBE_SKIP_IPV6;
127 ClientCloseDuringConnectInternal(kIPv6Loopback);
128}
129
130void SocketTest::TestServerCloseIPv4() {
131 ServerCloseInternal(kIPv4Loopback);
132}
133
134void SocketTest::TestServerCloseIPv6() {
135 MAYBE_SKIP_IPV6;
136 ServerCloseInternal(kIPv6Loopback);
137}
138
139void SocketTest::TestCloseInClosedCallbackIPv4() {
140 CloseInClosedCallbackInternal(kIPv4Loopback);
141}
142
143void SocketTest::TestCloseInClosedCallbackIPv6() {
144 MAYBE_SKIP_IPV6;
145 CloseInClosedCallbackInternal(kIPv6Loopback);
146}
147
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000148void SocketTest::TestDeleteInReadCallbackIPv4() {
149 DeleteInReadCallbackInternal(kIPv4Loopback);
150}
151
152void SocketTest::TestDeleteInReadCallbackIPv6() {
153 MAYBE_SKIP_IPV6;
154 DeleteInReadCallbackInternal(kIPv6Loopback);
155}
156
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000157void SocketTest::TestSocketServerWaitIPv4() {
158 SocketServerWaitInternal(kIPv4Loopback);
159}
160
161void SocketTest::TestSocketServerWaitIPv6() {
162 MAYBE_SKIP_IPV6;
163 SocketServerWaitInternal(kIPv6Loopback);
164}
165
166void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800167 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000168}
169
170void SocketTest::TestTcpIPv6() {
171 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800172 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000173}
174
175void SocketTest::TestSingleFlowControlCallbackIPv4() {
176 SingleFlowControlCallbackInternal(kIPv4Loopback);
177}
178
179void SocketTest::TestSingleFlowControlCallbackIPv6() {
180 MAYBE_SKIP_IPV6;
181 SingleFlowControlCallbackInternal(kIPv6Loopback);
182}
183
184void SocketTest::TestUdpIPv4() {
185 UdpInternal(kIPv4Loopback);
186}
187
188void SocketTest::TestUdpIPv6() {
189 MAYBE_SKIP_IPV6;
190 UdpInternal(kIPv6Loopback);
191}
192
193void SocketTest::TestUdpReadyToSendIPv4() {
194#if !defined(WEBRTC_MAC)
195 // TODO(ronghuawu): Enable this test on mac/ios.
196 UdpReadyToSend(kIPv4Loopback);
197#endif
198}
199
200void SocketTest::TestUdpReadyToSendIPv6() {
201#if defined(WEBRTC_WIN)
202 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
203 MAYBE_SKIP_IPV6;
204 UdpReadyToSend(kIPv6Loopback);
205#endif
206}
207
208void SocketTest::TestGetSetOptionsIPv4() {
209 GetSetOptionsInternal(kIPv4Loopback);
210}
211
212void SocketTest::TestGetSetOptionsIPv6() {
213 MAYBE_SKIP_IPV6;
214 GetSetOptionsInternal(kIPv6Loopback);
215}
216
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700217void SocketTest::TestSocketRecvTimestampIPv4() {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200218 SocketRecvTimestamp(kIPv4Loopback);
219}
220
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700221void SocketTest::TestSocketRecvTimestampIPv6() {
222 MAYBE_SKIP_IPV6;
223 SocketRecvTimestamp(kIPv6Loopback);
224}
225
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000226// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
227// values on Windows, but an empty address of the same family on Linux/MacOS X.
228bool IsUnspecOrEmptyIP(const IPAddress& address) {
229#if !defined(WEBRTC_WIN)
230 return IPIsAny(address);
231#else
232 return address.family() == AF_UNSPEC;
233#endif
234}
235
236void SocketTest::ConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700237 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000238 SocketAddress accept_addr;
239
240 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200241 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200242 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000243 sink.Monitor(client.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200244 EXPECT_EQ(Socket::CS_CLOSED, client->GetState());
Jonas Olssonabbe8412018-04-03 13:40:05 +0200245 EXPECT_TRUE(IsUnspecOrEmptyIP(client->GetLocalAddress().ipaddr()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000246
247 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200248 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200249 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000250 sink.Monitor(server.get());
251 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
252 EXPECT_EQ(0, server->Listen(5));
Niels Möllerd0b88792021-08-12 10:32:30 +0200253 EXPECT_EQ(Socket::CS_CONNECTING, server->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000254
255 // Ensure no pending server connections, since we haven't done anything yet.
kwibergd0d81482017-04-18 03:18:22 -0700256 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800257 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000258 EXPECT_TRUE(accept_addr.IsNil());
259
260 // Attempt connect to listening socket.
261 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
262 EXPECT_FALSE(client->GetLocalAddress().IsNil());
263 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
264
265 // Client is connecting, outcome not yet determined.
Niels Möllerd0b88792021-08-12 10:32:30 +0200266 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700267 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
268 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000269
270 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700271 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200272 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000273 ASSERT_TRUE(accepted);
274 EXPECT_FALSE(accept_addr.IsNil());
275 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
276
277 // Connected from server perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200278 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000279 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
280 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
281
282 // Connected from client perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200283 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700284 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
285 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000286 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
287 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
288}
289
290void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
Ali Tofigh7fa90572022-03-17 15:47:49 +0100291 absl::string_view host) {
kwibergd0d81482017-04-18 03:18:22 -0700292 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000293 SocketAddress accept_addr;
294
295 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200296 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200297 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000298 sink.Monitor(client.get());
299
300 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200301 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200302 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000303 sink.Monitor(server.get());
304 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
305 EXPECT_EQ(0, server->Listen(5));
306
307 // Attempt connect to listening socket.
308 SocketAddress dns_addr(server->GetLocalAddress());
309 dns_addr.SetIP(host);
310 EXPECT_EQ(0, client->Connect(dns_addr));
311 // TODO: Bind when doing DNS lookup.
Yves Gerey665174f2018-06-19 15:03:05 +0200312 // EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000313
314 // Client is connecting, outcome not yet determined.
Niels Möllerd0b88792021-08-12 10:32:30 +0200315 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700316 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
317 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000318
319 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700320 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200321 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000322 ASSERT_TRUE(accepted);
323 EXPECT_FALSE(accept_addr.IsNil());
324 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
325
326 // Connected from server perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200327 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000328 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
329 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
330
331 // Connected from client perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200332 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700333 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
334 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000335 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
336 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
337}
338
339void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700340 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000341 SocketAddress accept_addr;
342
343 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200344 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200345 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000346 sink.Monitor(client.get());
347
348 // Create server, but don't listen yet.
Niels Möllerd0b88792021-08-12 10:32:30 +0200349 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200350 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000351 sink.Monitor(server.get());
352 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
353
354 // Attempt connect to a non-existent socket.
355 // We don't connect to the server socket created above, since on
356 // MacOS it takes about 75 seconds to get back an error!
357 SocketAddress bogus_addr(loopback, 65535);
358 EXPECT_EQ(0, client->Connect(bogus_addr));
359
360 // Wait for connection to fail (ECONNREFUSED).
Niels Möllerd0b88792021-08-12 10:32:30 +0200361 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700362 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
363 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000364 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
365
366 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700367 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800368 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000369 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
370}
371
372void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700373 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000374 SocketAddress accept_addr;
375
376 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200377 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200378 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000379 sink.Monitor(client.get());
380
381 // Create server, but don't listen yet.
Niels Möllerd0b88792021-08-12 10:32:30 +0200382 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200383 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000384 sink.Monitor(server.get());
385 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
386
387 // Attempt connect to a non-existent host.
388 // We don't connect to the server socket created above, since on
389 // MacOS it takes about 75 seconds to get back an error!
390 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
391 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
392
393 // Wait for connection to fail (EHOSTNOTFOUND).
394 bool dns_lookup_finished = false;
Niels Möllerd0b88792021-08-12 10:32:30 +0200395 WAIT_(client->GetState() == Socket::CS_CLOSED, kTimeout, dns_lookup_finished);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000396 if (!dns_lookup_finished) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100397 RTC_LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
Jonas Olssonb2b20312020-01-14 12:11:31 +0100398 "seconds.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000399 return;
400 }
401
Niels Möllerd0b88792021-08-12 10:32:30 +0200402 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700403 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
404 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000405 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
406 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700407 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800408 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000409 EXPECT_TRUE(accept_addr.IsNil());
410}
411
412void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
413 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200414 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200415 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000416 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
417 EXPECT_EQ(0, server->Listen(5));
418
419 // Create a client and put in to CS_CLOSED state.
Niels Möllerd0b88792021-08-12 10:32:30 +0200420 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200421 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000422 EXPECT_EQ(0, client->Close());
Niels Möllerd0b88792021-08-12 10:32:30 +0200423 EXPECT_EQ(Socket::CS_CLOSED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000424
425 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
426 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200427 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000428}
429
430void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
431 // Create server and listen.
kwibergd0d81482017-04-18 03:18:22 -0700432 StreamSink sink;
Niels Möllerd0b88792021-08-12 10:32:30 +0200433 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200434 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000435 sink.Monitor(server.get());
436 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
437 EXPECT_EQ(0, server->Listen(5));
438 // Create client, connect.
Niels Möllerd0b88792021-08-12 10:32:30 +0200439 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200440 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000441 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200442 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000443 // Try to connect again. Should fail, but not interfere with original attempt.
444 EXPECT_EQ(SOCKET_ERROR,
445 client->Connect(SocketAddress(server->GetLocalAddress())));
446
447 // Accept the original connection.
448 SocketAddress accept_addr;
kwibergd0d81482017-04-18 03:18:22 -0700449 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200450 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000451 ASSERT_TRUE(accepted);
452 EXPECT_FALSE(accept_addr.IsNil());
453
454 // Check the states and addresses.
Niels Möllerd0b88792021-08-12 10:32:30 +0200455 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000456 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
457 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
Niels Möllerd0b88792021-08-12 10:32:30 +0200458 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000459 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
460 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
461
462 // Try to connect again, to an unresolved hostname.
463 // Shouldn't break anything.
Yves Gerey665174f2018-06-19 15:03:05 +0200464 EXPECT_EQ(SOCKET_ERROR, client->Connect(SocketAddress(
465 "localhost", server->GetLocalAddress().port())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200466 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
467 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000468 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
469 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
470}
471
472void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700473 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000474
475 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200476 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200477 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000478 sink.Monitor(client.get());
479
480 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200481 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200482 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000483 sink.Monitor(server.get());
484 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
485 EXPECT_EQ(0, server->Listen(5));
486
487 // Attempt connect to listening socket.
488 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
489
490 // Close down the server while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700491 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000492 server->Close();
493
494 // This should fail the connection for the client. Clean up.
Niels Möllerd0b88792021-08-12 10:32:30 +0200495 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700496 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000497 client->Close();
498}
499
500void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700501 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000502 SocketAddress accept_addr;
503
504 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200505 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200506 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000507 sink.Monitor(client.get());
508
509 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200510 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200511 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000512 sink.Monitor(server.get());
513 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
514 EXPECT_EQ(0, server->Listen(5));
515
516 // Attempt connect to listening socket.
517 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
518
519 // Close down the client while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700520 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000521 client->Close();
522
523 // The connection should still be able to be accepted.
Niels Möllerd0b88792021-08-12 10:32:30 +0200524 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000525 ASSERT_TRUE(accepted);
526 sink.Monitor(accepted.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200527 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000528
529 // The accepted socket should then close (possibly with err, timing-related)
Niels Möllerd0b88792021-08-12 10:32:30 +0200530 EXPECT_EQ_WAIT(Socket::CS_CLOSED, accepted->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700531 EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE) ||
532 sink.Check(accepted.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000533
534 // The client should not get a close event.
kwibergd0d81482017-04-18 03:18:22 -0700535 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000536}
537
538void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700539 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000540 SocketAddress accept_addr;
541
542 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200543 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200544 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000545 sink.Monitor(client.get());
546
547 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200548 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200549 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000550 sink.Monitor(server.get());
551 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
552 EXPECT_EQ(0, server->Listen(5));
553
554 // Attempt connection.
555 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
556
557 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700558 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200559 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000560 ASSERT_TRUE(accepted);
561 sink.Monitor(accepted.get());
562
563 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200564 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700565 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000566 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
567 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
568
569 // Send data to the client, and then close the connection.
570 EXPECT_EQ(1, accepted->Send("a", 1));
571 accepted->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200572 EXPECT_EQ(Socket::CS_CLOSED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000573
574 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700575 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
576 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
Niels Möllerd0b88792021-08-12 10:32:30 +0200577 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000578
579 // Ensure the data can be read.
580 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200581 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000582 EXPECT_EQ('a', buffer[0]);
583
584 // Now we should close, but the remote address will remain.
Niels Möllerd0b88792021-08-12 10:32:30 +0200585 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700586 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000587 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
588
589 // The closer should not get a close signal.
kwibergd0d81482017-04-18 03:18:22 -0700590 EXPECT_FALSE(sink.Check(accepted.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000591 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
592
593 // And the closee should only get a single signal.
594 Thread::Current()->ProcessMessages(0);
kwibergd0d81482017-04-18 03:18:22 -0700595 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000596
597 // Close down the client and ensure all is good.
598 client->Close();
kwibergd0d81482017-04-18 03:18:22 -0700599 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000600 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
601}
602
603class SocketCloser : public sigslot::has_slots<> {
604 public:
Niels Möllerd0b88792021-08-12 10:32:30 +0200605 void OnClose(Socket* socket, int error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000606 socket->Close(); // Deleting here would blow up the vector of handlers
607 // for the socket's signal.
608 }
609};
610
611void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700612 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000613 SocketCloser closer;
614 SocketAddress accept_addr;
615
616 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200617 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200618 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000619 sink.Monitor(client.get());
620 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
621
622 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200623 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200624 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000625 sink.Monitor(server.get());
626 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
627 EXPECT_EQ(0, server->Listen(5));
628
629 // Attempt connection.
630 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
631
632 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700633 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200634 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000635 ASSERT_TRUE(accepted);
636 sink.Monitor(accepted.get());
637
638 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200639 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700640 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000641 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
642 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
643
644 // Send data to the client, and then close the connection.
645 accepted->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200646 EXPECT_EQ(Socket::CS_CLOSED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000647
648 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700649 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
Niels Möllerd0b88792021-08-12 10:32:30 +0200650 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000651
652 // Now we should be closed and invalidated
Niels Möllerd0b88792021-08-12 10:32:30 +0200653 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700654 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000655 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
656}
657
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000658// Helper class specifically for the test below.
659class SocketDeleter : public sigslot::has_slots<> {
660 public:
Niels Möllerd0b88792021-08-12 10:32:30 +0200661 explicit SocketDeleter(std::unique_ptr<Socket> socket)
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000662 : socket_(std::move(socket)) {}
663
Niels Möllerd0b88792021-08-12 10:32:30 +0200664 void Delete(Socket* other) { socket_.reset(); }
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000665
666 bool deleted() const { return socket_ == nullptr; }
667
668 private:
Niels Möllerd0b88792021-08-12 10:32:30 +0200669 std::unique_ptr<Socket> socket_;
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000670};
671
672// Tested deleting a socket within another socket's read callback. A previous
673// iteration of the select loop failed in this situation, if both sockets
674// became readable at the same time.
675void SocketTest::DeleteInReadCallbackInternal(const IPAddress& loopback) {
Niels Möllerd0b88792021-08-12 10:32:30 +0200676 std::unique_ptr<Socket> socket1(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200677 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
Niels Möllerd0b88792021-08-12 10:32:30 +0200678 std::unique_ptr<Socket> socket2(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200679 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000680 EXPECT_EQ(0, socket1->Bind(SocketAddress(loopback, 0)));
681 EXPECT_EQ(0, socket2->Bind(SocketAddress(loopback, 0)));
682 EXPECT_EQ(3, socket1->SendTo("foo", 3, socket1->GetLocalAddress()));
683 EXPECT_EQ(3, socket2->SendTo("bar", 3, socket1->GetLocalAddress()));
684 // Sleep a while to ensure sends are both completed at the same time.
685 Thread::SleepMs(1000);
686
687 // Configure the helper class to delete socket 2 when socket 1 has a read
688 // event.
689 SocketDeleter deleter(std::move(socket2));
690 socket1->SignalReadEvent.connect(&deleter, &SocketDeleter::Delete);
691 EXPECT_TRUE_WAIT(deleter.deleted(), kTimeout);
692}
693
Tomas Gunnarssonabdb4702020-09-05 18:43:36 +0200694class Sleeper : public MessageHandlerAutoCleanup {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000695 public:
Steve Anton9de3aac2017-10-24 10:08:26 -0700696 void OnMessage(Message* msg) override { Thread::Current()->SleepMs(500); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000697};
698
699void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700700 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000701 SocketAddress accept_addr;
702
703 // Create & connect server and client sockets.
Niels Möllerd0b88792021-08-12 10:32:30 +0200704 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200705 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
Niels Möllerd0b88792021-08-12 10:32:30 +0200706 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200707 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000708 sink.Monitor(client.get());
709 sink.Monitor(server.get());
710 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
711 EXPECT_EQ(0, server->Listen(5));
712
713 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
kwibergd0d81482017-04-18 03:18:22 -0700714 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000715
Niels Möllerd0b88792021-08-12 10:32:30 +0200716 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000717 ASSERT_TRUE(accepted);
718 sink.Monitor(accepted.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200719 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000720 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
721 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
722
Niels Möllerd0b88792021-08-12 10:32:30 +0200723 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700724 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
725 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000726 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
727 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
728
729 // Do an i/o operation, triggering an eventual callback.
kwibergd0d81482017-04-18 03:18:22 -0700730 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000731 char buf[1024] = {0};
732
733 EXPECT_EQ(1024, client->Send(buf, 1024));
kwibergd0d81482017-04-18 03:18:22 -0700734 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000735
736 // Shouldn't signal when blocked in a thread Send, where process_io is false.
tommie7251592017-07-14 14:44:46 -0700737 std::unique_ptr<Thread> thread(Thread::CreateWithSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000738 thread->Start();
739 Sleeper sleeper;
Niels Möllerd0b88792021-08-12 10:32:30 +0200740 TypedMessageData<Socket*> data(client.get());
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700741 thread->Send(RTC_FROM_HERE, &sleeper, 0, &data);
kwibergd0d81482017-04-18 03:18:22 -0700742 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000743
744 // But should signal when process_io is true.
kwibergd0d81482017-04-18 03:18:22 -0700745 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200746 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000747}
748
Yves Gerey665174f2018-06-19 15:03:05 +0200749void SocketTest::TcpInternal(const IPAddress& loopback,
750 size_t data_size,
751 ptrdiff_t max_send_size) {
kwibergd0d81482017-04-18 03:18:22 -0700752 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000753 SocketAddress accept_addr;
754
jbauchf2a2bf42016-02-03 16:45:32 -0800755 // Create receiving client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200756 std::unique_ptr<Socket> receiver(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200757 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800758 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000759
760 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200761 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200762 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000763 sink.Monitor(server.get());
764 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
765 EXPECT_EQ(0, server->Listen(5));
766
767 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800768 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000769
jbauchf2a2bf42016-02-03 16:45:32 -0800770 // Accept connection which will be used for sending.
kwibergd0d81482017-04-18 03:18:22 -0700771 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200772 std::unique_ptr<Socket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800773 ASSERT_TRUE(sender);
774 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000775
776 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200777 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700778 EXPECT_TRUE(sink.Check(receiver.get(), SSE_OPEN));
jbauchf2a2bf42016-02-03 16:45:32 -0800779 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
780 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
781
782 // Create test data.
783 rtc::Buffer send_buffer(0, data_size);
784 rtc::Buffer recv_buffer(0, data_size);
785 for (size_t i = 0; i < data_size; ++i) {
786 char ch = static_cast<char>(i % 256);
787 send_buffer.AppendData(&ch, sizeof(ch));
788 }
danilchapb7b9dca2016-08-05 05:55:43 -0700789 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000790
791 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800792 size_t sent_size = 0;
793 bool writable = true;
794 bool send_called = false;
795 bool readable = false;
796 bool recv_called = false;
797 while (recv_buffer.size() < send_buffer.size()) {
798 // Send as much as we can while we're cleared to send.
799 while (writable && sent_size < send_buffer.size()) {
800 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
801 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
802 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000803 // The first Send() after connecting or getting writability should
804 // succeed and send some data.
805 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800806 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000807 }
808 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800809 EXPECT_LE(sent, unsent_size);
810 sent_size += sent;
811 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 05:55:43 -0700812 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-03 16:45:32 -0800813 if (sent < unsent_size) {
814 // If max_send_size is limiting the amount to send per call such
815 // that the sent amount is less than the unsent amount, we simulate
816 // that the socket is no longer writable.
817 writable = false;
818 }
819 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000820 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800821 ASSERT_TRUE(sender->IsBlocking());
822 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000823 }
824 }
825
826 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800827 while (recv_buffer.size() < sent_size) {
828 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000829 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700830 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), SSE_READ), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800831 readable = true;
832 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000833 }
834
835 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 05:55:43 -0700836 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000837
jbauchf2a2bf42016-02-03 16:45:32 -0800838 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000839 // The first Recv() after getting readability should succeed and receive
840 // some data.
841 // TODO: The following line is disabled due to flakey pulse
842 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800843 // EXPECT_GT(recved_size, 0);
844 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000845 }
jbauchf2a2bf42016-02-03 16:45:32 -0800846 if (recved_size >= 0) {
847 EXPECT_LE(static_cast<size_t>(recved_size),
Yves Gerey665174f2018-06-19 15:03:05 +0200848 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 05:55:43 -0700849 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000850 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800851 ASSERT_TRUE(receiver->IsBlocking());
852 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000853 }
854 }
855
jbauchf2a2bf42016-02-03 16:45:32 -0800856 // Once all that we've sent has been received, expect to be able to send
857 // again.
858 if (!writable) {
kwibergd0d81482017-04-18 03:18:22 -0700859 ASSERT_TRUE_WAIT(sink.Check(sender.get(), SSE_WRITE), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800860 writable = true;
861 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000862 }
863 }
864
865 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800866 EXPECT_EQ(data_size, sent_size);
867 EXPECT_EQ(data_size, recv_buffer.size());
868 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000869
870 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800871 sender->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200872 EXPECT_EQ_WAIT(Socket::CS_CLOSED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700873 EXPECT_TRUE(sink.Check(receiver.get(), SSE_CLOSE));
jbauchf2a2bf42016-02-03 16:45:32 -0800874 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000875}
876
877void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700878 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000879 SocketAddress accept_addr;
880
881 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200882 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200883 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000884 sink.Monitor(client.get());
885
886 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200887 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200888 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000889 sink.Monitor(server.get());
890 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
891 EXPECT_EQ(0, server->Listen(5));
892
893 // Attempt connection.
894 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
895
896 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700897 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200898 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000899 ASSERT_TRUE(accepted);
900 sink.Monitor(accepted.get());
901
902 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200903 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700904 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000905 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
906 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
907
908 // Expect a writable callback from the connect.
kwibergd0d81482017-04-18 03:18:22 -0700909 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000910
911 // Fill the socket buffer.
912 char buf[1024 * 16] = {0};
913 int sends = 0;
Yves Gerey665174f2018-06-19 15:03:05 +0200914 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {
915 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000916 EXPECT_TRUE(accepted->IsBlocking());
917
918 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700919 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000920
921 // Pull data.
922 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200923 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000924 }
925
926 // Expect at least one additional writable callback.
kwibergd0d81482017-04-18 03:18:22 -0700927 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000928
929 // Adding data in response to the writeable callback shouldn't cause infinite
930 // callbacks.
931 int extras = 0;
932 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800933 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000934 rtc::Thread::Current()->ProcessMessages(1);
kwibergd0d81482017-04-18 03:18:22 -0700935 if (sink.Check(accepted.get(), SSE_WRITE)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000936 extras++;
937 }
938 }
939 EXPECT_LT(extras, 2);
940
941 // Close down.
942 accepted->Close();
943 client->Close();
944}
945
946void SocketTest::UdpInternal(const IPAddress& loopback) {
947 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
948 // Test basic bind and connect behavior.
Niels Möller50f7c2c2021-09-08 14:05:16 +0200949 Socket* socket = socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM);
Niels Möllerd0b88792021-08-12 10:32:30 +0200950 EXPECT_EQ(Socket::CS_CLOSED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000951 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
952 SocketAddress addr1 = socket->GetLocalAddress();
953 EXPECT_EQ(0, socket->Connect(addr1));
Niels Möllerd0b88792021-08-12 10:32:30 +0200954 EXPECT_EQ(Socket::CS_CONNECTED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000955 socket->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200956 EXPECT_EQ(Socket::CS_CLOSED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000957 delete socket;
958
959 // Test send/receive behavior.
Niels Möller50f7c2c2021-09-08 14:05:16 +0200960 auto client1 = std::make_unique<TestClient>(
961 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, addr1)));
962 auto client2 = std::make_unique<TestClient>(
963 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, empty)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000964
965 SocketAddress addr2;
966 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
967 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
968
969 SocketAddress addr3;
970 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
971 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
972 EXPECT_EQ(addr3, addr1);
973 // TODO: figure out what the intent is here
974 for (int i = 0; i < 10; ++i) {
Niels Möller50f7c2c2021-09-08 14:05:16 +0200975 client2 = std::make_unique<TestClient>(
976 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, empty)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000977
978 SocketAddress addr4;
979 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
980 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
981 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
982
983 SocketAddress addr5;
984 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
985 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
986 EXPECT_EQ(addr5, addr1);
987
988 addr2 = addr4;
989 }
990}
991
992void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
993 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
994 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
995 // documentation.
996 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
Yves Gerey665174f2018-06-19 15:03:05 +0200997 std::string dest =
998 (loopback.family() == AF_INET6) ? "2001:db8::1" : "192.0.2.0";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000999 SocketAddress test_addr(dest, 2345);
1000
1001 // Test send
Niels Möller50f7c2c2021-09-08 14:05:16 +02001002 auto client = std::make_unique<TestClient>(
1003 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, empty)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001004 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -07001005 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001006 // Init the test packet just to avoid memcheck warning.
1007 memset(test_packet.get(), 0, test_packet_size);
1008 // Set the send buffer size to the same size as the test packet to have a
1009 // better chance to get EWOULDBLOCK.
1010 int send_buffer_size = test_packet_size;
1011#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
1012 send_buffer_size /= 2;
1013#endif
1014 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
1015
1016 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001017 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001018 int sent_packet_num = 0;
1019 int expected_error = EWOULDBLOCK;
1020 while (start_ms + kTimeout > Time()) {
1021 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
1022 ++sent_packet_num;
1023 if (ret != test_packet_size) {
1024 error = client->GetError();
1025 if (error == expected_error) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001026 RTC_LOG(LS_INFO) << "Got expected error code after sending "
1027 << sent_packet_num << " packets.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001028 break;
1029 }
1030 }
1031 }
1032 EXPECT_EQ(expected_error, error);
1033 EXPECT_FALSE(client->ready_to_send());
1034 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
Mirko Bonadei675513b2017-11-09 11:09:25 +01001035 RTC_LOG(LS_INFO) << "Got SignalReadyToSend";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001036}
1037
1038void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
Niels Möllerd0b88792021-08-12 10:32:30 +02001039 std::unique_ptr<Socket> socket(
Niels Möller50f7c2c2021-09-08 14:05:16 +02001040 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001041 socket->Bind(SocketAddress(loopback, 0));
1042
1043 // Check SNDBUF/RCVBUF.
1044 const int desired_size = 12345;
1045#if defined(WEBRTC_LINUX)
1046 // Yes, really. It's in the kernel source.
1047 const int expected_size = desired_size * 2;
1048#else // !WEBRTC_LINUX
1049 const int expected_size = desired_size;
1050#endif // !WEBRTC_LINUX
1051 int recv_size = 0;
1052 int send_size = 0;
1053 // get the initial sizes
1054 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1055 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1056 // set our desired sizes
1057 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
1058 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
1059 // get the sizes again
1060 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1061 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1062 // make sure they are right
1063 ASSERT_EQ(expected_size, recv_size);
1064 ASSERT_EQ(expected_size, send_size);
1065
1066 // Check that we can't set NODELAY on a UDP socket.
1067 int current_nd, desired_nd = 1;
1068 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1069 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -08001070
1071#if defined(WEBRTC_POSIX)
1072 // Check DSCP.
1073 int current_dscp, desired_dscp = 1;
1074 ASSERT_NE(-1, socket->GetOption(Socket::OPT_DSCP, &current_dscp));
1075 ASSERT_NE(-1, socket->SetOption(Socket::OPT_DSCP, desired_dscp));
1076 ASSERT_NE(-1, socket->GetOption(Socket::OPT_DSCP, &current_dscp));
1077 ASSERT_EQ(desired_dscp, current_dscp);
1078#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001079}
1080
Stefan Holmer9131efd2016-05-23 18:19:26 +02001081void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
1082 std::unique_ptr<Socket> socket(
Niels Möller50f7c2c2021-09-08 14:05:16 +02001083 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
Stefan Holmer9131efd2016-05-23 18:19:26 +02001084 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1085 SocketAddress address = socket->GetLocalAddress();
1086
nissedeb95f32016-11-28 01:54:54 -08001087 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001088 socket->SendTo("foo", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001089 int64_t recv_timestamp_1;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001090 char buffer[3];
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001091 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1);
1092 EXPECT_GT(recv_timestamp_1, -1);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001093
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001094 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001095 Thread::SleepMs(kTimeBetweenPacketsMs);
1096
nissedeb95f32016-11-28 01:54:54 -08001097 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001098 socket->SendTo("bar", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001099 int64_t recv_timestamp_2;
1100 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2);
1101
1102 int64_t system_time_diff = send_time_2 - send_time_1;
1103 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1104 // Compare against the system time at the point of sending, because
1105 // SleepMs may not sleep for exactly the requested time.
1106 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001107}
1108
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001109} // namespace rtc