blob: 8e76d343f6eaddf8e6e6276ab6cd0af13a05a6fa [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/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080027#include "rtc_base/net_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/socket_address.h"
29#include "rtc_base/socket_server.h"
Yves Gerey3e707812018-11-28 16:47:49 +010030#include "rtc_base/socket_unittest.h"
Steve Anton10542f22019-01-11 09:11:00 -080031#include "rtc_base/test_client.h"
32#include "rtc_base/test_utils.h"
Yves Gerey3e707812018-11-28 16:47:49 +010033#include "rtc_base/third_party/sigslot/sigslot.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080035#include "rtc_base/time_utils.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000036
37namespace rtc {
38
kwibergd0d81482017-04-18 03:18:22 -070039using webrtc::testing::SSE_CLOSE;
40using webrtc::testing::SSE_ERROR;
41using webrtc::testing::SSE_OPEN;
42using webrtc::testing::SSE_READ;
43using webrtc::testing::SSE_WRITE;
44using webrtc::testing::StreamSink;
45
Mirko Bonadei675513b2017-11-09 11:09:25 +010046#define MAYBE_SKIP_IPV6 \
47 if (!HasIPv6Enabled()) { \
48 RTC_LOG(LS_INFO) << "No IPv6... skipping"; \
49 return; \
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000050 }
51
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070052// Data size to be used in TcpInternal tests.
53static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000054
55void SocketTest::TestConnectIPv4() {
56 ConnectInternal(kIPv4Loopback);
57}
58
59void SocketTest::TestConnectIPv6() {
60 MAYBE_SKIP_IPV6;
61 ConnectInternal(kIPv6Loopback);
62}
63
64void SocketTest::TestConnectWithDnsLookupIPv4() {
65 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
66}
67
68void SocketTest::TestConnectWithDnsLookupIPv6() {
69 // TODO: Enable this when DNS resolution supports IPv6.
Mirko Bonadei675513b2017-11-09 11:09:25 +010070 RTC_LOG(LS_INFO) << "Skipping IPv6 DNS test";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000071 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
72}
73
74void SocketTest::TestConnectFailIPv4() {
75 ConnectFailInternal(kIPv4Loopback);
76}
77
78void SocketTest::TestConnectFailIPv6() {
79 MAYBE_SKIP_IPV6;
80 ConnectFailInternal(kIPv6Loopback);
81}
82
83void SocketTest::TestConnectWithDnsLookupFailIPv4() {
84 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
85}
86
87void SocketTest::TestConnectWithDnsLookupFailIPv6() {
88 MAYBE_SKIP_IPV6;
89 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
90}
91
92void SocketTest::TestConnectWithClosedSocketIPv4() {
93 ConnectWithClosedSocketInternal(kIPv4Loopback);
94}
95
96void SocketTest::TestConnectWithClosedSocketIPv6() {
97 MAYBE_SKIP_IPV6;
98 ConnectWithClosedSocketInternal(kIPv6Loopback);
99}
100
101void SocketTest::TestConnectWhileNotClosedIPv4() {
102 ConnectWhileNotClosedInternal(kIPv4Loopback);
103}
104
105void SocketTest::TestConnectWhileNotClosedIPv6() {
106 MAYBE_SKIP_IPV6;
107 ConnectWhileNotClosedInternal(kIPv6Loopback);
108}
109
110void SocketTest::TestServerCloseDuringConnectIPv4() {
111 ServerCloseDuringConnectInternal(kIPv4Loopback);
112}
113
114void SocketTest::TestServerCloseDuringConnectIPv6() {
115 MAYBE_SKIP_IPV6;
116 ServerCloseDuringConnectInternal(kIPv6Loopback);
117}
118
119void SocketTest::TestClientCloseDuringConnectIPv4() {
120 ClientCloseDuringConnectInternal(kIPv4Loopback);
121}
122
123void SocketTest::TestClientCloseDuringConnectIPv6() {
124 MAYBE_SKIP_IPV6;
125 ClientCloseDuringConnectInternal(kIPv6Loopback);
126}
127
128void SocketTest::TestServerCloseIPv4() {
129 ServerCloseInternal(kIPv4Loopback);
130}
131
132void SocketTest::TestServerCloseIPv6() {
133 MAYBE_SKIP_IPV6;
134 ServerCloseInternal(kIPv6Loopback);
135}
136
137void SocketTest::TestCloseInClosedCallbackIPv4() {
138 CloseInClosedCallbackInternal(kIPv4Loopback);
139}
140
141void SocketTest::TestCloseInClosedCallbackIPv6() {
142 MAYBE_SKIP_IPV6;
143 CloseInClosedCallbackInternal(kIPv6Loopback);
144}
145
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000146void SocketTest::TestDeleteInReadCallbackIPv4() {
147 DeleteInReadCallbackInternal(kIPv4Loopback);
148}
149
150void SocketTest::TestDeleteInReadCallbackIPv6() {
151 MAYBE_SKIP_IPV6;
152 DeleteInReadCallbackInternal(kIPv6Loopback);
153}
154
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000155void SocketTest::TestSocketServerWaitIPv4() {
156 SocketServerWaitInternal(kIPv4Loopback);
157}
158
159void SocketTest::TestSocketServerWaitIPv6() {
160 MAYBE_SKIP_IPV6;
161 SocketServerWaitInternal(kIPv6Loopback);
162}
163
164void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800165 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000166}
167
168void SocketTest::TestTcpIPv6() {
169 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800170 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000171}
172
173void SocketTest::TestSingleFlowControlCallbackIPv4() {
174 SingleFlowControlCallbackInternal(kIPv4Loopback);
175}
176
177void SocketTest::TestSingleFlowControlCallbackIPv6() {
178 MAYBE_SKIP_IPV6;
179 SingleFlowControlCallbackInternal(kIPv6Loopback);
180}
181
182void SocketTest::TestUdpIPv4() {
183 UdpInternal(kIPv4Loopback);
184}
185
186void SocketTest::TestUdpIPv6() {
187 MAYBE_SKIP_IPV6;
188 UdpInternal(kIPv6Loopback);
189}
190
191void SocketTest::TestUdpReadyToSendIPv4() {
192#if !defined(WEBRTC_MAC)
193 // TODO(ronghuawu): Enable this test on mac/ios.
194 UdpReadyToSend(kIPv4Loopback);
195#endif
196}
197
198void SocketTest::TestUdpReadyToSendIPv6() {
199#if defined(WEBRTC_WIN)
200 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
201 MAYBE_SKIP_IPV6;
202 UdpReadyToSend(kIPv6Loopback);
203#endif
204}
205
206void SocketTest::TestGetSetOptionsIPv4() {
207 GetSetOptionsInternal(kIPv4Loopback);
208}
209
210void SocketTest::TestGetSetOptionsIPv6() {
211 MAYBE_SKIP_IPV6;
212 GetSetOptionsInternal(kIPv6Loopback);
213}
214
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700215void SocketTest::TestSocketRecvTimestampIPv4() {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200216 SocketRecvTimestamp(kIPv4Loopback);
217}
218
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700219void SocketTest::TestSocketRecvTimestampIPv6() {
220 MAYBE_SKIP_IPV6;
221 SocketRecvTimestamp(kIPv6Loopback);
222}
223
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000224// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
225// values on Windows, but an empty address of the same family on Linux/MacOS X.
226bool IsUnspecOrEmptyIP(const IPAddress& address) {
227#if !defined(WEBRTC_WIN)
228 return IPIsAny(address);
229#else
230 return address.family() == AF_UNSPEC;
231#endif
232}
233
234void SocketTest::ConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700235 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000236 SocketAddress accept_addr;
237
238 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200239 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200240 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000241 sink.Monitor(client.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200242 EXPECT_EQ(Socket::CS_CLOSED, client->GetState());
Jonas Olssonabbe8412018-04-03 13:40:05 +0200243 EXPECT_TRUE(IsUnspecOrEmptyIP(client->GetLocalAddress().ipaddr()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000244
245 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200246 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200247 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000248 sink.Monitor(server.get());
249 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
250 EXPECT_EQ(0, server->Listen(5));
Niels Möllerd0b88792021-08-12 10:32:30 +0200251 EXPECT_EQ(Socket::CS_CONNECTING, server->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000252
253 // Ensure no pending server connections, since we haven't done anything yet.
kwibergd0d81482017-04-18 03:18:22 -0700254 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800255 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000256 EXPECT_TRUE(accept_addr.IsNil());
257
258 // Attempt connect to listening socket.
259 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
260 EXPECT_FALSE(client->GetLocalAddress().IsNil());
261 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
262
263 // Client is connecting, outcome not yet determined.
Niels Möllerd0b88792021-08-12 10:32:30 +0200264 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700265 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
266 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000267
268 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700269 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200270 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000271 ASSERT_TRUE(accepted);
272 EXPECT_FALSE(accept_addr.IsNil());
273 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
274
275 // Connected from server perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200276 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000277 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
278 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
279
280 // Connected from client perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200281 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700282 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
283 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000284 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
285 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
286}
287
288void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
Ali Tofigh7fa90572022-03-17 15:47:49 +0100289 absl::string_view host) {
kwibergd0d81482017-04-18 03:18:22 -0700290 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000291 SocketAddress accept_addr;
292
293 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200294 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200295 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000296 sink.Monitor(client.get());
297
298 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200299 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200300 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000301 sink.Monitor(server.get());
302 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
303 EXPECT_EQ(0, server->Listen(5));
304
305 // Attempt connect to listening socket.
306 SocketAddress dns_addr(server->GetLocalAddress());
307 dns_addr.SetIP(host);
308 EXPECT_EQ(0, client->Connect(dns_addr));
309 // TODO: Bind when doing DNS lookup.
Yves Gerey665174f2018-06-19 15:03:05 +0200310 // EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000311
312 // Client is connecting, outcome not yet determined.
Niels Möllerd0b88792021-08-12 10:32:30 +0200313 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700314 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
315 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000316
317 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700318 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200319 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000320 ASSERT_TRUE(accepted);
321 EXPECT_FALSE(accept_addr.IsNil());
322 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
323
324 // Connected from server perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200325 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000326 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
327 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
328
329 // Connected from client perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200330 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700331 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
332 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000333 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
334 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
335}
336
337void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700338 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000339 SocketAddress accept_addr;
340
341 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200342 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200343 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000344 sink.Monitor(client.get());
345
346 // Create server, but don't listen yet.
Niels Möllerd0b88792021-08-12 10:32:30 +0200347 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200348 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000349 sink.Monitor(server.get());
350 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
351
352 // Attempt connect to a non-existent socket.
353 // We don't connect to the server socket created above, since on
354 // MacOS it takes about 75 seconds to get back an error!
355 SocketAddress bogus_addr(loopback, 65535);
356 EXPECT_EQ(0, client->Connect(bogus_addr));
357
358 // Wait for connection to fail (ECONNREFUSED).
Niels Möllerd0b88792021-08-12 10:32:30 +0200359 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700360 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
361 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000362 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
363
364 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700365 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800366 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000367 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
368}
369
370void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700371 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000372 SocketAddress accept_addr;
373
374 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200375 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200376 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000377 sink.Monitor(client.get());
378
379 // Create server, but don't listen yet.
Niels Möllerd0b88792021-08-12 10:32:30 +0200380 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200381 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000382 sink.Monitor(server.get());
383 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
384
385 // Attempt connect to a non-existent host.
386 // We don't connect to the server socket created above, since on
387 // MacOS it takes about 75 seconds to get back an error!
388 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
389 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
390
391 // Wait for connection to fail (EHOSTNOTFOUND).
392 bool dns_lookup_finished = false;
Niels Möllerd0b88792021-08-12 10:32:30 +0200393 WAIT_(client->GetState() == Socket::CS_CLOSED, kTimeout, dns_lookup_finished);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000394 if (!dns_lookup_finished) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100395 RTC_LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
Jonas Olssonb2b20312020-01-14 12:11:31 +0100396 "seconds.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000397 return;
398 }
399
Niels Möllerd0b88792021-08-12 10:32:30 +0200400 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700401 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
402 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000403 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
404 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700405 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800406 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000407 EXPECT_TRUE(accept_addr.IsNil());
408}
409
410void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
411 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200412 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200413 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000414 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
415 EXPECT_EQ(0, server->Listen(5));
416
417 // Create a client and put in to CS_CLOSED state.
Niels Möllerd0b88792021-08-12 10:32:30 +0200418 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200419 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000420 EXPECT_EQ(0, client->Close());
Niels Möllerd0b88792021-08-12 10:32:30 +0200421 EXPECT_EQ(Socket::CS_CLOSED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000422
423 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
424 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200425 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000426}
427
428void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
429 // Create server and listen.
kwibergd0d81482017-04-18 03:18:22 -0700430 StreamSink sink;
Niels Möllerd0b88792021-08-12 10:32:30 +0200431 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200432 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000433 sink.Monitor(server.get());
434 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
435 EXPECT_EQ(0, server->Listen(5));
436 // Create client, connect.
Niels Möllerd0b88792021-08-12 10:32:30 +0200437 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200438 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000439 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200440 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000441 // Try to connect again. Should fail, but not interfere with original attempt.
442 EXPECT_EQ(SOCKET_ERROR,
443 client->Connect(SocketAddress(server->GetLocalAddress())));
444
445 // Accept the original connection.
446 SocketAddress accept_addr;
kwibergd0d81482017-04-18 03:18:22 -0700447 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200448 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000449 ASSERT_TRUE(accepted);
450 EXPECT_FALSE(accept_addr.IsNil());
451
452 // Check the states and addresses.
Niels Möllerd0b88792021-08-12 10:32:30 +0200453 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000454 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
455 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
Niels Möllerd0b88792021-08-12 10:32:30 +0200456 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000457 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
458 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
459
460 // Try to connect again, to an unresolved hostname.
461 // Shouldn't break anything.
Yves Gerey665174f2018-06-19 15:03:05 +0200462 EXPECT_EQ(SOCKET_ERROR, client->Connect(SocketAddress(
463 "localhost", server->GetLocalAddress().port())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200464 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
465 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000466 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
467 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
468}
469
470void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700471 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000472
473 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200474 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200475 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000476 sink.Monitor(client.get());
477
478 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200479 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200480 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000481 sink.Monitor(server.get());
482 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
483 EXPECT_EQ(0, server->Listen(5));
484
485 // Attempt connect to listening socket.
486 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
487
488 // Close down the server while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700489 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000490 server->Close();
491
492 // This should fail the connection for the client. Clean up.
Niels Möllerd0b88792021-08-12 10:32:30 +0200493 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700494 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000495 client->Close();
496}
497
498void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700499 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000500 SocketAddress accept_addr;
501
502 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200503 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200504 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000505 sink.Monitor(client.get());
506
507 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200508 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200509 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000510 sink.Monitor(server.get());
511 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
512 EXPECT_EQ(0, server->Listen(5));
513
514 // Attempt connect to listening socket.
515 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
516
517 // Close down the client while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700518 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000519 client->Close();
520
521 // The connection should still be able to be accepted.
Niels Möllerd0b88792021-08-12 10:32:30 +0200522 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000523 ASSERT_TRUE(accepted);
524 sink.Monitor(accepted.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200525 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000526
527 // The accepted socket should then close (possibly with err, timing-related)
Niels Möllerd0b88792021-08-12 10:32:30 +0200528 EXPECT_EQ_WAIT(Socket::CS_CLOSED, accepted->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700529 EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE) ||
530 sink.Check(accepted.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000531
532 // The client should not get a close event.
kwibergd0d81482017-04-18 03:18:22 -0700533 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000534}
535
536void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700537 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000538 SocketAddress accept_addr;
539
540 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200541 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200542 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000543 sink.Monitor(client.get());
544
545 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200546 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200547 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000548 sink.Monitor(server.get());
549 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
550 EXPECT_EQ(0, server->Listen(5));
551
552 // Attempt connection.
553 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
554
555 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700556 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200557 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000558 ASSERT_TRUE(accepted);
559 sink.Monitor(accepted.get());
560
561 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200562 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700563 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000564 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
565 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
566
567 // Send data to the client, and then close the connection.
568 EXPECT_EQ(1, accepted->Send("a", 1));
569 accepted->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200570 EXPECT_EQ(Socket::CS_CLOSED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000571
572 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700573 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
574 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
Niels Möllerd0b88792021-08-12 10:32:30 +0200575 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000576
577 // Ensure the data can be read.
578 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200579 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000580 EXPECT_EQ('a', buffer[0]);
581
582 // Now we should close, but the remote address will remain.
Niels Möllerd0b88792021-08-12 10:32:30 +0200583 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700584 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000585 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
586
587 // The closer should not get a close signal.
kwibergd0d81482017-04-18 03:18:22 -0700588 EXPECT_FALSE(sink.Check(accepted.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000589 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
590
591 // And the closee should only get a single signal.
592 Thread::Current()->ProcessMessages(0);
kwibergd0d81482017-04-18 03:18:22 -0700593 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000594
595 // Close down the client and ensure all is good.
596 client->Close();
kwibergd0d81482017-04-18 03:18:22 -0700597 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000598 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
599}
600
601class SocketCloser : public sigslot::has_slots<> {
602 public:
Niels Möllerd0b88792021-08-12 10:32:30 +0200603 void OnClose(Socket* socket, int error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000604 socket->Close(); // Deleting here would blow up the vector of handlers
605 // for the socket's signal.
606 }
607};
608
609void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700610 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000611 SocketCloser closer;
612 SocketAddress accept_addr;
613
614 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200615 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200616 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000617 sink.Monitor(client.get());
618 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
619
620 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200621 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200622 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000623 sink.Monitor(server.get());
624 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
625 EXPECT_EQ(0, server->Listen(5));
626
627 // Attempt connection.
628 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
629
630 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700631 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200632 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000633 ASSERT_TRUE(accepted);
634 sink.Monitor(accepted.get());
635
636 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200637 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700638 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000639 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
640 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
641
642 // Send data to the client, and then close the connection.
643 accepted->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200644 EXPECT_EQ(Socket::CS_CLOSED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000645
646 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700647 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
Niels Möllerd0b88792021-08-12 10:32:30 +0200648 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000649
650 // Now we should be closed and invalidated
Niels Möllerd0b88792021-08-12 10:32:30 +0200651 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700652 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000653 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
654}
655
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000656// Helper class specifically for the test below.
657class SocketDeleter : public sigslot::has_slots<> {
658 public:
Niels Möllerd0b88792021-08-12 10:32:30 +0200659 explicit SocketDeleter(std::unique_ptr<Socket> socket)
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000660 : socket_(std::move(socket)) {}
661
Niels Möllerd0b88792021-08-12 10:32:30 +0200662 void Delete(Socket* other) { socket_.reset(); }
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000663
664 bool deleted() const { return socket_ == nullptr; }
665
666 private:
Niels Möllerd0b88792021-08-12 10:32:30 +0200667 std::unique_ptr<Socket> socket_;
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000668};
669
670// Tested deleting a socket within another socket's read callback. A previous
671// iteration of the select loop failed in this situation, if both sockets
672// became readable at the same time.
673void SocketTest::DeleteInReadCallbackInternal(const IPAddress& loopback) {
Niels Möllerd0b88792021-08-12 10:32:30 +0200674 std::unique_ptr<Socket> socket1(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200675 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
Niels Möllerd0b88792021-08-12 10:32:30 +0200676 std::unique_ptr<Socket> socket2(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200677 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000678 EXPECT_EQ(0, socket1->Bind(SocketAddress(loopback, 0)));
679 EXPECT_EQ(0, socket2->Bind(SocketAddress(loopback, 0)));
680 EXPECT_EQ(3, socket1->SendTo("foo", 3, socket1->GetLocalAddress()));
681 EXPECT_EQ(3, socket2->SendTo("bar", 3, socket1->GetLocalAddress()));
682 // Sleep a while to ensure sends are both completed at the same time.
683 Thread::SleepMs(1000);
684
685 // Configure the helper class to delete socket 2 when socket 1 has a read
686 // event.
687 SocketDeleter deleter(std::move(socket2));
688 socket1->SignalReadEvent.connect(&deleter, &SocketDeleter::Delete);
689 EXPECT_TRUE_WAIT(deleter.deleted(), kTimeout);
690}
691
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000692void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700693 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000694 SocketAddress accept_addr;
695
696 // Create & connect server and client sockets.
Niels Möllerd0b88792021-08-12 10:32:30 +0200697 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200698 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
Niels Möllerd0b88792021-08-12 10:32:30 +0200699 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200700 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000701 sink.Monitor(client.get());
702 sink.Monitor(server.get());
703 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
704 EXPECT_EQ(0, server->Listen(5));
705
706 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
kwibergd0d81482017-04-18 03:18:22 -0700707 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000708
Niels Möllerd0b88792021-08-12 10:32:30 +0200709 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000710 ASSERT_TRUE(accepted);
711 sink.Monitor(accepted.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200712 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000713 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
714 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
715
Niels Möllerd0b88792021-08-12 10:32:30 +0200716 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700717 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
718 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000719 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
720 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
721
722 // Do an i/o operation, triggering an eventual callback.
kwibergd0d81482017-04-18 03:18:22 -0700723 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000724 char buf[1024] = {0};
725
726 EXPECT_EQ(1024, client->Send(buf, 1024));
kwibergd0d81482017-04-18 03:18:22 -0700727 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000728
729 // Shouldn't signal when blocked in a thread Send, where process_io is false.
tommie7251592017-07-14 14:44:46 -0700730 std::unique_ptr<Thread> thread(Thread::CreateWithSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000731 thread->Start();
Danil Chapovalov9e09a1f2022-09-08 18:38:10 +0200732 thread->BlockingCall([] { Thread::SleepMs(500); });
kwibergd0d81482017-04-18 03:18:22 -0700733 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000734
735 // But should signal when process_io is true.
kwibergd0d81482017-04-18 03:18:22 -0700736 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200737 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000738}
739
Yves Gerey665174f2018-06-19 15:03:05 +0200740void SocketTest::TcpInternal(const IPAddress& loopback,
741 size_t data_size,
742 ptrdiff_t max_send_size) {
kwibergd0d81482017-04-18 03:18:22 -0700743 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000744 SocketAddress accept_addr;
745
jbauchf2a2bf42016-02-03 16:45:32 -0800746 // Create receiving client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200747 std::unique_ptr<Socket> receiver(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200748 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800749 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000750
751 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200752 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200753 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000754 sink.Monitor(server.get());
755 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
756 EXPECT_EQ(0, server->Listen(5));
757
758 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800759 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000760
jbauchf2a2bf42016-02-03 16:45:32 -0800761 // Accept connection which will be used for sending.
kwibergd0d81482017-04-18 03:18:22 -0700762 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200763 std::unique_ptr<Socket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800764 ASSERT_TRUE(sender);
765 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000766
767 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200768 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700769 EXPECT_TRUE(sink.Check(receiver.get(), SSE_OPEN));
jbauchf2a2bf42016-02-03 16:45:32 -0800770 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
771 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
772
773 // Create test data.
774 rtc::Buffer send_buffer(0, data_size);
775 rtc::Buffer recv_buffer(0, data_size);
776 for (size_t i = 0; i < data_size; ++i) {
777 char ch = static_cast<char>(i % 256);
778 send_buffer.AppendData(&ch, sizeof(ch));
779 }
danilchapb7b9dca2016-08-05 05:55:43 -0700780 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000781
782 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800783 size_t sent_size = 0;
784 bool writable = true;
785 bool send_called = false;
786 bool readable = false;
787 bool recv_called = false;
788 while (recv_buffer.size() < send_buffer.size()) {
789 // Send as much as we can while we're cleared to send.
790 while (writable && sent_size < send_buffer.size()) {
791 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
792 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
793 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000794 // The first Send() after connecting or getting writability should
795 // succeed and send some data.
796 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800797 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000798 }
799 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800800 EXPECT_LE(sent, unsent_size);
801 sent_size += sent;
802 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 05:55:43 -0700803 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-03 16:45:32 -0800804 if (sent < unsent_size) {
805 // If max_send_size is limiting the amount to send per call such
806 // that the sent amount is less than the unsent amount, we simulate
807 // that the socket is no longer writable.
808 writable = false;
809 }
810 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000811 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800812 ASSERT_TRUE(sender->IsBlocking());
813 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000814 }
815 }
816
817 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800818 while (recv_buffer.size() < sent_size) {
819 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000820 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700821 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), SSE_READ), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800822 readable = true;
823 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000824 }
825
826 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 05:55:43 -0700827 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000828
jbauchf2a2bf42016-02-03 16:45:32 -0800829 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000830 // The first Recv() after getting readability should succeed and receive
831 // some data.
832 // TODO: The following line is disabled due to flakey pulse
833 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800834 // EXPECT_GT(recved_size, 0);
835 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000836 }
jbauchf2a2bf42016-02-03 16:45:32 -0800837 if (recved_size >= 0) {
838 EXPECT_LE(static_cast<size_t>(recved_size),
Yves Gerey665174f2018-06-19 15:03:05 +0200839 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 05:55:43 -0700840 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000841 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800842 ASSERT_TRUE(receiver->IsBlocking());
843 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000844 }
845 }
846
jbauchf2a2bf42016-02-03 16:45:32 -0800847 // Once all that we've sent has been received, expect to be able to send
848 // again.
849 if (!writable) {
kwibergd0d81482017-04-18 03:18:22 -0700850 ASSERT_TRUE_WAIT(sink.Check(sender.get(), SSE_WRITE), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800851 writable = true;
852 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000853 }
854 }
855
856 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800857 EXPECT_EQ(data_size, sent_size);
858 EXPECT_EQ(data_size, recv_buffer.size());
859 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000860
861 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800862 sender->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200863 EXPECT_EQ_WAIT(Socket::CS_CLOSED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700864 EXPECT_TRUE(sink.Check(receiver.get(), SSE_CLOSE));
jbauchf2a2bf42016-02-03 16:45:32 -0800865 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000866}
867
868void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700869 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000870 SocketAddress accept_addr;
871
872 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200873 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200874 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000875 sink.Monitor(client.get());
876
877 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200878 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200879 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000880 sink.Monitor(server.get());
881 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
882 EXPECT_EQ(0, server->Listen(5));
883
884 // Attempt connection.
885 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
886
887 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700888 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200889 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000890 ASSERT_TRUE(accepted);
891 sink.Monitor(accepted.get());
892
893 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200894 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700895 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000896 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
897 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
898
899 // Expect a writable callback from the connect.
kwibergd0d81482017-04-18 03:18:22 -0700900 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000901
902 // Fill the socket buffer.
903 char buf[1024 * 16] = {0};
904 int sends = 0;
Yves Gerey665174f2018-06-19 15:03:05 +0200905 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {
906 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000907 EXPECT_TRUE(accepted->IsBlocking());
908
909 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700910 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000911
912 // Pull data.
913 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200914 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000915 }
916
917 // Expect at least one additional writable callback.
kwibergd0d81482017-04-18 03:18:22 -0700918 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000919
920 // Adding data in response to the writeable callback shouldn't cause infinite
921 // callbacks.
922 int extras = 0;
923 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800924 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000925 rtc::Thread::Current()->ProcessMessages(1);
kwibergd0d81482017-04-18 03:18:22 -0700926 if (sink.Check(accepted.get(), SSE_WRITE)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000927 extras++;
928 }
929 }
930 EXPECT_LT(extras, 2);
931
932 // Close down.
933 accepted->Close();
934 client->Close();
935}
936
937void SocketTest::UdpInternal(const IPAddress& loopback) {
938 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
939 // Test basic bind and connect behavior.
Niels Möller50f7c2c2021-09-08 14:05:16 +0200940 Socket* socket = socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM);
Niels Möllerd0b88792021-08-12 10:32:30 +0200941 EXPECT_EQ(Socket::CS_CLOSED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000942 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
943 SocketAddress addr1 = socket->GetLocalAddress();
944 EXPECT_EQ(0, socket->Connect(addr1));
Niels Möllerd0b88792021-08-12 10:32:30 +0200945 EXPECT_EQ(Socket::CS_CONNECTED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000946 socket->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200947 EXPECT_EQ(Socket::CS_CLOSED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000948 delete socket;
949
950 // Test send/receive behavior.
Niels Möller50f7c2c2021-09-08 14:05:16 +0200951 auto client1 = std::make_unique<TestClient>(
952 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, addr1)));
953 auto client2 = std::make_unique<TestClient>(
954 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, empty)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000955
956 SocketAddress addr2;
957 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
958 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
959
960 SocketAddress addr3;
961 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
962 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
963 EXPECT_EQ(addr3, addr1);
964 // TODO: figure out what the intent is here
965 for (int i = 0; i < 10; ++i) {
Niels Möller50f7c2c2021-09-08 14:05:16 +0200966 client2 = std::make_unique<TestClient>(
967 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, empty)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000968
969 SocketAddress addr4;
970 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
971 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
972 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
973
974 SocketAddress addr5;
975 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
976 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
977 EXPECT_EQ(addr5, addr1);
978
979 addr2 = addr4;
980 }
981}
982
983void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
984 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
985 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
986 // documentation.
987 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
Yves Gerey665174f2018-06-19 15:03:05 +0200988 std::string dest =
989 (loopback.family() == AF_INET6) ? "2001:db8::1" : "192.0.2.0";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000990 SocketAddress test_addr(dest, 2345);
991
992 // Test send
Niels Möller50f7c2c2021-09-08 14:05:16 +0200993 auto client = std::make_unique<TestClient>(
994 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, empty)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000995 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -0700996 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000997 // Init the test packet just to avoid memcheck warning.
998 memset(test_packet.get(), 0, test_packet_size);
999 // Set the send buffer size to the same size as the test packet to have a
1000 // better chance to get EWOULDBLOCK.
1001 int send_buffer_size = test_packet_size;
1002#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
1003 send_buffer_size /= 2;
1004#endif
1005 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
1006
1007 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001008 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001009 int sent_packet_num = 0;
1010 int expected_error = EWOULDBLOCK;
1011 while (start_ms + kTimeout > Time()) {
1012 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
1013 ++sent_packet_num;
1014 if (ret != test_packet_size) {
1015 error = client->GetError();
1016 if (error == expected_error) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001017 RTC_LOG(LS_INFO) << "Got expected error code after sending "
1018 << sent_packet_num << " packets.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001019 break;
1020 }
1021 }
1022 }
1023 EXPECT_EQ(expected_error, error);
1024 EXPECT_FALSE(client->ready_to_send());
1025 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
Mirko Bonadei675513b2017-11-09 11:09:25 +01001026 RTC_LOG(LS_INFO) << "Got SignalReadyToSend";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001027}
1028
1029void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
Niels Möllerd0b88792021-08-12 10:32:30 +02001030 std::unique_ptr<Socket> socket(
Niels Möller50f7c2c2021-09-08 14:05:16 +02001031 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001032 socket->Bind(SocketAddress(loopback, 0));
1033
1034 // Check SNDBUF/RCVBUF.
1035 const int desired_size = 12345;
1036#if defined(WEBRTC_LINUX)
1037 // Yes, really. It's in the kernel source.
1038 const int expected_size = desired_size * 2;
1039#else // !WEBRTC_LINUX
1040 const int expected_size = desired_size;
1041#endif // !WEBRTC_LINUX
1042 int recv_size = 0;
1043 int send_size = 0;
1044 // get the initial sizes
1045 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1046 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1047 // set our desired sizes
1048 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
1049 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
1050 // get the sizes again
1051 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1052 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1053 // make sure they are right
1054 ASSERT_EQ(expected_size, recv_size);
1055 ASSERT_EQ(expected_size, send_size);
1056
1057 // Check that we can't set NODELAY on a UDP socket.
1058 int current_nd, desired_nd = 1;
1059 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1060 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -08001061
1062#if defined(WEBRTC_POSIX)
1063 // Check DSCP.
1064 int current_dscp, desired_dscp = 1;
1065 ASSERT_NE(-1, socket->GetOption(Socket::OPT_DSCP, &current_dscp));
1066 ASSERT_NE(-1, socket->SetOption(Socket::OPT_DSCP, desired_dscp));
1067 ASSERT_NE(-1, socket->GetOption(Socket::OPT_DSCP, &current_dscp));
1068 ASSERT_EQ(desired_dscp, current_dscp);
1069#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001070}
1071
Stefan Holmer9131efd2016-05-23 18:19:26 +02001072void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001073 StreamSink sink;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001074 std::unique_ptr<Socket> socket(
Niels Möller50f7c2c2021-09-08 14:05:16 +02001075 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
Stefan Holmer9131efd2016-05-23 18:19:26 +02001076 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1077 SocketAddress address = socket->GetLocalAddress();
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001078 sink.Monitor(socket.get());
Stefan Holmer9131efd2016-05-23 18:19:26 +02001079
nissedeb95f32016-11-28 01:54:54 -08001080 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001081 socket->SendTo("foo", 3, address);
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001082
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001083 int64_t recv_timestamp_1;
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001084 // Wait until data is available.
1085 EXPECT_TRUE_WAIT(sink.Check(socket.get(), SSE_READ), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001086 char buffer[3];
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001087 ASSERT_GT(socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1), 0);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001088
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001089 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001090 Thread::SleepMs(kTimeBetweenPacketsMs);
1091
nissedeb95f32016-11-28 01:54:54 -08001092 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001093 socket->SendTo("bar", 3, address);
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001094 // Wait until data is available.
1095 EXPECT_TRUE_WAIT(sink.Check(socket.get(), SSE_READ), kTimeout);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001096 int64_t recv_timestamp_2;
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001097 ASSERT_GT(socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2), 0);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001098
1099 int64_t system_time_diff = send_time_2 - send_time_1;
1100 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1101 // Compare against the system time at the point of sending, because
1102 // SleepMs may not sleep for exactly the requested time.
1103 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001104}
1105
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001106} // namespace rtc