blob: 40da8c26cf24ca2867a5fce9c61bbe88ccc319a5 [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
Per Kjellander3daf6962022-11-08 18:23:43 +010017#include <cstddef>
18#include <cstdint>
jbauch555604a2016-04-26 03:13:22 -070019#include <memory>
20
Karl Wiberg918f50c2018-07-05 11:40:33 +020021#include "absl/memory/memory.h"
Ali Tofigh7fa90572022-03-17 15:47:49 +010022#include "absl/strings/string_view.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080024#include "rtc_base/async_packet_socket.h"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "rtc_base/async_udp_socket.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "rtc_base/buffer.h"
27#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 16:47:49 +010028#include "rtc_base/logging.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
Per Kjellander3daf6962022-11-08 18:23:43 +0100226void SocketTest::TestUdpSocketRecvTimestampUseRtcEpochIPv4() {
227 UdpSocketRecvTimestampUseRtcEpoch(kIPv4Loopback);
228}
229
230void SocketTest::TestUdpSocketRecvTimestampUseRtcEpochIPv6() {
231 MAYBE_SKIP_IPV6;
232 UdpSocketRecvTimestampUseRtcEpoch(kIPv6Loopback);
233}
234
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000235// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
236// values on Windows, but an empty address of the same family on Linux/MacOS X.
237bool IsUnspecOrEmptyIP(const IPAddress& address) {
238#if !defined(WEBRTC_WIN)
239 return IPIsAny(address);
240#else
241 return address.family() == AF_UNSPEC;
242#endif
243}
244
245void SocketTest::ConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700246 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000247 SocketAddress accept_addr;
248
249 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200250 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200251 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000252 sink.Monitor(client.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200253 EXPECT_EQ(Socket::CS_CLOSED, client->GetState());
Jonas Olssonabbe8412018-04-03 13:40:05 +0200254 EXPECT_TRUE(IsUnspecOrEmptyIP(client->GetLocalAddress().ipaddr()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000255
256 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200257 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200258 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000259 sink.Monitor(server.get());
260 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
261 EXPECT_EQ(0, server->Listen(5));
Niels Möllerd0b88792021-08-12 10:32:30 +0200262 EXPECT_EQ(Socket::CS_CONNECTING, server->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000263
264 // Ensure no pending server connections, since we haven't done anything yet.
kwibergd0d81482017-04-18 03:18:22 -0700265 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800266 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000267 EXPECT_TRUE(accept_addr.IsNil());
268
269 // Attempt connect to listening socket.
270 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
271 EXPECT_FALSE(client->GetLocalAddress().IsNil());
272 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
273
274 // Client is connecting, outcome not yet determined.
Niels Möllerd0b88792021-08-12 10:32:30 +0200275 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700276 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
277 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000278
279 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700280 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200281 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000282 ASSERT_TRUE(accepted);
283 EXPECT_FALSE(accept_addr.IsNil());
284 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
285
286 // Connected from server perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200287 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000288 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
289 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
290
291 // Connected from client perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200292 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700293 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
294 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000295 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
296 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
297}
298
299void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
Ali Tofigh7fa90572022-03-17 15:47:49 +0100300 absl::string_view host) {
kwibergd0d81482017-04-18 03:18:22 -0700301 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000302 SocketAddress accept_addr;
303
304 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200305 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200306 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000307 sink.Monitor(client.get());
308
309 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200310 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200311 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000312 sink.Monitor(server.get());
313 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
314 EXPECT_EQ(0, server->Listen(5));
315
316 // Attempt connect to listening socket.
317 SocketAddress dns_addr(server->GetLocalAddress());
318 dns_addr.SetIP(host);
319 EXPECT_EQ(0, client->Connect(dns_addr));
320 // TODO: Bind when doing DNS lookup.
Yves Gerey665174f2018-06-19 15:03:05 +0200321 // EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000322
323 // Client is connecting, outcome not yet determined.
Niels Möllerd0b88792021-08-12 10:32:30 +0200324 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700325 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
326 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000327
328 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700329 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200330 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000331 ASSERT_TRUE(accepted);
332 EXPECT_FALSE(accept_addr.IsNil());
333 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
334
335 // Connected from server perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200336 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000337 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
338 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
339
340 // Connected from client perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200341 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700342 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
343 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000344 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
345 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
346}
347
348void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700349 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000350 SocketAddress accept_addr;
351
352 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200353 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200354 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000355 sink.Monitor(client.get());
356
357 // Create server, but don't listen yet.
Niels Möllerd0b88792021-08-12 10:32:30 +0200358 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200359 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000360 sink.Monitor(server.get());
361 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
362
363 // Attempt connect to a non-existent socket.
364 // We don't connect to the server socket created above, since on
365 // MacOS it takes about 75 seconds to get back an error!
366 SocketAddress bogus_addr(loopback, 65535);
367 EXPECT_EQ(0, client->Connect(bogus_addr));
368
369 // Wait for connection to fail (ECONNREFUSED).
Niels Möllerd0b88792021-08-12 10:32:30 +0200370 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700371 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
372 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000373 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
374
375 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700376 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800377 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000378 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
379}
380
381void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700382 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000383 SocketAddress accept_addr;
384
385 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200386 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200387 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000388 sink.Monitor(client.get());
389
390 // Create server, but don't listen yet.
Niels Möllerd0b88792021-08-12 10:32:30 +0200391 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200392 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000393 sink.Monitor(server.get());
394 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
395
396 // Attempt connect to a non-existent host.
397 // We don't connect to the server socket created above, since on
398 // MacOS it takes about 75 seconds to get back an error!
399 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
400 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
401
402 // Wait for connection to fail (EHOSTNOTFOUND).
403 bool dns_lookup_finished = false;
Niels Möllerd0b88792021-08-12 10:32:30 +0200404 WAIT_(client->GetState() == Socket::CS_CLOSED, kTimeout, dns_lookup_finished);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000405 if (!dns_lookup_finished) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100406 RTC_LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
Jonas Olssonb2b20312020-01-14 12:11:31 +0100407 "seconds.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000408 return;
409 }
410
Niels Möllerd0b88792021-08-12 10:32:30 +0200411 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700412 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
413 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000414 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
415 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700416 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800417 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000418 EXPECT_TRUE(accept_addr.IsNil());
419}
420
421void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
422 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200423 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200424 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000425 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
426 EXPECT_EQ(0, server->Listen(5));
427
428 // Create a client and put in to CS_CLOSED state.
Niels Möllerd0b88792021-08-12 10:32:30 +0200429 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200430 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000431 EXPECT_EQ(0, client->Close());
Niels Möllerd0b88792021-08-12 10:32:30 +0200432 EXPECT_EQ(Socket::CS_CLOSED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000433
434 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
435 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200436 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000437}
438
439void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
440 // Create server and listen.
kwibergd0d81482017-04-18 03:18:22 -0700441 StreamSink sink;
Niels Möllerd0b88792021-08-12 10:32:30 +0200442 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200443 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000444 sink.Monitor(server.get());
445 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
446 EXPECT_EQ(0, server->Listen(5));
447 // Create client, connect.
Niels Möllerd0b88792021-08-12 10:32:30 +0200448 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200449 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000450 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200451 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000452 // Try to connect again. Should fail, but not interfere with original attempt.
453 EXPECT_EQ(SOCKET_ERROR,
454 client->Connect(SocketAddress(server->GetLocalAddress())));
455
456 // Accept the original connection.
457 SocketAddress accept_addr;
kwibergd0d81482017-04-18 03:18:22 -0700458 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200459 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000460 ASSERT_TRUE(accepted);
461 EXPECT_FALSE(accept_addr.IsNil());
462
463 // Check the states and addresses.
Niels Möllerd0b88792021-08-12 10:32:30 +0200464 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000465 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
466 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
Niels Möllerd0b88792021-08-12 10:32:30 +0200467 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000468 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
469 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
470
471 // Try to connect again, to an unresolved hostname.
472 // Shouldn't break anything.
Yves Gerey665174f2018-06-19 15:03:05 +0200473 EXPECT_EQ(SOCKET_ERROR, client->Connect(SocketAddress(
474 "localhost", server->GetLocalAddress().port())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200475 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
476 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000477 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
478 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
479}
480
481void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700482 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000483
484 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200485 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200486 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000487 sink.Monitor(client.get());
488
489 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200490 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200491 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000492 sink.Monitor(server.get());
493 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
494 EXPECT_EQ(0, server->Listen(5));
495
496 // Attempt connect to listening socket.
497 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
498
499 // Close down the server while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700500 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000501 server->Close();
502
503 // This should fail the connection for the client. Clean up.
Niels Möllerd0b88792021-08-12 10:32:30 +0200504 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700505 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000506 client->Close();
507}
508
509void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700510 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000511 SocketAddress accept_addr;
512
513 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200514 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200515 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000516 sink.Monitor(client.get());
517
518 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200519 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200520 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000521 sink.Monitor(server.get());
522 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
523 EXPECT_EQ(0, server->Listen(5));
524
525 // Attempt connect to listening socket.
526 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
527
528 // Close down the client while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700529 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000530 client->Close();
531
532 // The connection should still be able to be accepted.
Niels Möllerd0b88792021-08-12 10:32:30 +0200533 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000534 ASSERT_TRUE(accepted);
535 sink.Monitor(accepted.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200536 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000537
538 // The accepted socket should then close (possibly with err, timing-related)
Niels Möllerd0b88792021-08-12 10:32:30 +0200539 EXPECT_EQ_WAIT(Socket::CS_CLOSED, accepted->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700540 EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE) ||
541 sink.Check(accepted.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000542
543 // The client should not get a close event.
kwibergd0d81482017-04-18 03:18:22 -0700544 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000545}
546
547void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700548 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000549 SocketAddress accept_addr;
550
551 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200552 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200553 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000554 sink.Monitor(client.get());
555
556 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200557 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200558 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000559 sink.Monitor(server.get());
560 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
561 EXPECT_EQ(0, server->Listen(5));
562
563 // Attempt connection.
564 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
565
566 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700567 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200568 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000569 ASSERT_TRUE(accepted);
570 sink.Monitor(accepted.get());
571
572 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200573 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700574 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000575 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
576 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
577
578 // Send data to the client, and then close the connection.
579 EXPECT_EQ(1, accepted->Send("a", 1));
580 accepted->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200581 EXPECT_EQ(Socket::CS_CLOSED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000582
583 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700584 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
585 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
Niels Möllerd0b88792021-08-12 10:32:30 +0200586 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000587
588 // Ensure the data can be read.
589 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200590 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000591 EXPECT_EQ('a', buffer[0]);
592
593 // Now we should close, but the remote address will remain.
Niels Möllerd0b88792021-08-12 10:32:30 +0200594 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700595 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000596 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
597
598 // The closer should not get a close signal.
kwibergd0d81482017-04-18 03:18:22 -0700599 EXPECT_FALSE(sink.Check(accepted.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000600 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
601
602 // And the closee should only get a single signal.
603 Thread::Current()->ProcessMessages(0);
kwibergd0d81482017-04-18 03:18:22 -0700604 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000605
606 // Close down the client and ensure all is good.
607 client->Close();
kwibergd0d81482017-04-18 03:18:22 -0700608 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000609 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
610}
611
612class SocketCloser : public sigslot::has_slots<> {
613 public:
Niels Möllerd0b88792021-08-12 10:32:30 +0200614 void OnClose(Socket* socket, int error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000615 socket->Close(); // Deleting here would blow up the vector of handlers
616 // for the socket's signal.
617 }
618};
619
620void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700621 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000622 SocketCloser closer;
623 SocketAddress accept_addr;
624
625 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200626 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200627 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000628 sink.Monitor(client.get());
629 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
630
631 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200632 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200633 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000634 sink.Monitor(server.get());
635 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
636 EXPECT_EQ(0, server->Listen(5));
637
638 // Attempt connection.
639 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
640
641 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700642 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200643 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000644 ASSERT_TRUE(accepted);
645 sink.Monitor(accepted.get());
646
647 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200648 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700649 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000650 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
651 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
652
653 // Send data to the client, and then close the connection.
654 accepted->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200655 EXPECT_EQ(Socket::CS_CLOSED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000656
657 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700658 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
Niels Möllerd0b88792021-08-12 10:32:30 +0200659 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000660
661 // Now we should be closed and invalidated
Niels Möllerd0b88792021-08-12 10:32:30 +0200662 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700663 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000664 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
665}
666
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000667// Helper class specifically for the test below.
668class SocketDeleter : public sigslot::has_slots<> {
669 public:
Niels Möllerd0b88792021-08-12 10:32:30 +0200670 explicit SocketDeleter(std::unique_ptr<Socket> socket)
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000671 : socket_(std::move(socket)) {}
672
Niels Möllerd0b88792021-08-12 10:32:30 +0200673 void Delete(Socket* other) { socket_.reset(); }
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000674
675 bool deleted() const { return socket_ == nullptr; }
676
677 private:
Niels Möllerd0b88792021-08-12 10:32:30 +0200678 std::unique_ptr<Socket> socket_;
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000679};
680
681// Tested deleting a socket within another socket's read callback. A previous
682// iteration of the select loop failed in this situation, if both sockets
683// became readable at the same time.
684void SocketTest::DeleteInReadCallbackInternal(const IPAddress& loopback) {
Niels Möllerd0b88792021-08-12 10:32:30 +0200685 std::unique_ptr<Socket> socket1(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200686 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
Niels Möllerd0b88792021-08-12 10:32:30 +0200687 std::unique_ptr<Socket> socket2(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200688 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000689 EXPECT_EQ(0, socket1->Bind(SocketAddress(loopback, 0)));
690 EXPECT_EQ(0, socket2->Bind(SocketAddress(loopback, 0)));
691 EXPECT_EQ(3, socket1->SendTo("foo", 3, socket1->GetLocalAddress()));
692 EXPECT_EQ(3, socket2->SendTo("bar", 3, socket1->GetLocalAddress()));
693 // Sleep a while to ensure sends are both completed at the same time.
694 Thread::SleepMs(1000);
695
696 // Configure the helper class to delete socket 2 when socket 1 has a read
697 // event.
698 SocketDeleter deleter(std::move(socket2));
699 socket1->SignalReadEvent.connect(&deleter, &SocketDeleter::Delete);
700 EXPECT_TRUE_WAIT(deleter.deleted(), kTimeout);
701}
702
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000703void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700704 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000705 SocketAddress accept_addr;
706
707 // Create & connect server and client sockets.
Niels Möllerd0b88792021-08-12 10:32:30 +0200708 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200709 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
Niels Möllerd0b88792021-08-12 10:32:30 +0200710 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200711 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000712 sink.Monitor(client.get());
713 sink.Monitor(server.get());
714 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
715 EXPECT_EQ(0, server->Listen(5));
716
717 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
kwibergd0d81482017-04-18 03:18:22 -0700718 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000719
Niels Möllerd0b88792021-08-12 10:32:30 +0200720 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000721 ASSERT_TRUE(accepted);
722 sink.Monitor(accepted.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200723 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000724 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
725 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
726
Niels Möllerd0b88792021-08-12 10:32:30 +0200727 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700728 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
729 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000730 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
731 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
732
733 // Do an i/o operation, triggering an eventual callback.
kwibergd0d81482017-04-18 03:18:22 -0700734 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000735 char buf[1024] = {0};
736
737 EXPECT_EQ(1024, client->Send(buf, 1024));
kwibergd0d81482017-04-18 03:18:22 -0700738 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000739
740 // Shouldn't signal when blocked in a thread Send, where process_io is false.
tommie7251592017-07-14 14:44:46 -0700741 std::unique_ptr<Thread> thread(Thread::CreateWithSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000742 thread->Start();
Danil Chapovalov9e09a1f2022-09-08 18:38:10 +0200743 thread->BlockingCall([] { Thread::SleepMs(500); });
kwibergd0d81482017-04-18 03:18:22 -0700744 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000745
746 // But should signal when process_io is true.
kwibergd0d81482017-04-18 03:18:22 -0700747 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200748 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000749}
750
Yves Gerey665174f2018-06-19 15:03:05 +0200751void SocketTest::TcpInternal(const IPAddress& loopback,
752 size_t data_size,
753 ptrdiff_t max_send_size) {
kwibergd0d81482017-04-18 03:18:22 -0700754 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000755 SocketAddress accept_addr;
756
jbauchf2a2bf42016-02-03 16:45:32 -0800757 // Create receiving client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200758 std::unique_ptr<Socket> receiver(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200759 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800760 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000761
762 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200763 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200764 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000765 sink.Monitor(server.get());
766 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
767 EXPECT_EQ(0, server->Listen(5));
768
769 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800770 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000771
jbauchf2a2bf42016-02-03 16:45:32 -0800772 // Accept connection which will be used for sending.
kwibergd0d81482017-04-18 03:18:22 -0700773 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200774 std::unique_ptr<Socket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800775 ASSERT_TRUE(sender);
776 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000777
778 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200779 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700780 EXPECT_TRUE(sink.Check(receiver.get(), SSE_OPEN));
jbauchf2a2bf42016-02-03 16:45:32 -0800781 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
782 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
783
784 // Create test data.
785 rtc::Buffer send_buffer(0, data_size);
786 rtc::Buffer recv_buffer(0, data_size);
787 for (size_t i = 0; i < data_size; ++i) {
788 char ch = static_cast<char>(i % 256);
789 send_buffer.AppendData(&ch, sizeof(ch));
790 }
danilchapb7b9dca2016-08-05 05:55:43 -0700791 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000792
793 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800794 size_t sent_size = 0;
795 bool writable = true;
796 bool send_called = false;
797 bool readable = false;
798 bool recv_called = false;
799 while (recv_buffer.size() < send_buffer.size()) {
800 // Send as much as we can while we're cleared to send.
801 while (writable && sent_size < send_buffer.size()) {
802 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
803 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
804 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000805 // The first Send() after connecting or getting writability should
806 // succeed and send some data.
807 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800808 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000809 }
810 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800811 EXPECT_LE(sent, unsent_size);
812 sent_size += sent;
813 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 05:55:43 -0700814 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-03 16:45:32 -0800815 if (sent < unsent_size) {
816 // If max_send_size is limiting the amount to send per call such
817 // that the sent amount is less than the unsent amount, we simulate
818 // that the socket is no longer writable.
819 writable = false;
820 }
821 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000822 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800823 ASSERT_TRUE(sender->IsBlocking());
824 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000825 }
826 }
827
828 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800829 while (recv_buffer.size() < sent_size) {
830 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000831 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700832 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), SSE_READ), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800833 readable = true;
834 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000835 }
836
837 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 05:55:43 -0700838 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000839
jbauchf2a2bf42016-02-03 16:45:32 -0800840 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000841 // The first Recv() after getting readability should succeed and receive
842 // some data.
843 // TODO: The following line is disabled due to flakey pulse
844 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800845 // EXPECT_GT(recved_size, 0);
846 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000847 }
jbauchf2a2bf42016-02-03 16:45:32 -0800848 if (recved_size >= 0) {
849 EXPECT_LE(static_cast<size_t>(recved_size),
Yves Gerey665174f2018-06-19 15:03:05 +0200850 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 05:55:43 -0700851 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000852 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800853 ASSERT_TRUE(receiver->IsBlocking());
854 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000855 }
856 }
857
jbauchf2a2bf42016-02-03 16:45:32 -0800858 // Once all that we've sent has been received, expect to be able to send
859 // again.
860 if (!writable) {
kwibergd0d81482017-04-18 03:18:22 -0700861 ASSERT_TRUE_WAIT(sink.Check(sender.get(), SSE_WRITE), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800862 writable = true;
863 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000864 }
865 }
866
867 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800868 EXPECT_EQ(data_size, sent_size);
869 EXPECT_EQ(data_size, recv_buffer.size());
870 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000871
872 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800873 sender->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200874 EXPECT_EQ_WAIT(Socket::CS_CLOSED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700875 EXPECT_TRUE(sink.Check(receiver.get(), SSE_CLOSE));
jbauchf2a2bf42016-02-03 16:45:32 -0800876 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000877}
878
879void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700880 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000881 SocketAddress accept_addr;
882
883 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200884 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200885 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000886 sink.Monitor(client.get());
887
888 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200889 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200890 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000891 sink.Monitor(server.get());
892 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
893 EXPECT_EQ(0, server->Listen(5));
894
895 // Attempt connection.
896 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
897
898 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700899 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200900 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000901 ASSERT_TRUE(accepted);
902 sink.Monitor(accepted.get());
903
904 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200905 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700906 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000907 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
908 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
909
910 // Expect a writable callback from the connect.
kwibergd0d81482017-04-18 03:18:22 -0700911 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000912
913 // Fill the socket buffer.
914 char buf[1024 * 16] = {0};
915 int sends = 0;
Yves Gerey665174f2018-06-19 15:03:05 +0200916 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {
917 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000918 EXPECT_TRUE(accepted->IsBlocking());
919
920 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700921 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000922
923 // Pull data.
924 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200925 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000926 }
927
928 // Expect at least one additional writable callback.
kwibergd0d81482017-04-18 03:18:22 -0700929 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000930
931 // Adding data in response to the writeable callback shouldn't cause infinite
932 // callbacks.
933 int extras = 0;
934 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800935 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000936 rtc::Thread::Current()->ProcessMessages(1);
kwibergd0d81482017-04-18 03:18:22 -0700937 if (sink.Check(accepted.get(), SSE_WRITE)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000938 extras++;
939 }
940 }
941 EXPECT_LT(extras, 2);
942
943 // Close down.
944 accepted->Close();
945 client->Close();
946}
947
948void SocketTest::UdpInternal(const IPAddress& loopback) {
949 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
950 // Test basic bind and connect behavior.
Niels Möller50f7c2c2021-09-08 14:05:16 +0200951 Socket* socket = socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM);
Niels Möllerd0b88792021-08-12 10:32:30 +0200952 EXPECT_EQ(Socket::CS_CLOSED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000953 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
954 SocketAddress addr1 = socket->GetLocalAddress();
955 EXPECT_EQ(0, socket->Connect(addr1));
Niels Möllerd0b88792021-08-12 10:32:30 +0200956 EXPECT_EQ(Socket::CS_CONNECTED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000957 socket->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200958 EXPECT_EQ(Socket::CS_CLOSED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000959 delete socket;
960
961 // Test send/receive behavior.
Niels Möller50f7c2c2021-09-08 14:05:16 +0200962 auto client1 = std::make_unique<TestClient>(
963 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, addr1)));
964 auto client2 = std::make_unique<TestClient>(
965 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, empty)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000966
967 SocketAddress addr2;
968 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
969 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
970
971 SocketAddress addr3;
972 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
973 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
974 EXPECT_EQ(addr3, addr1);
975 // TODO: figure out what the intent is here
976 for (int i = 0; i < 10; ++i) {
Niels Möller50f7c2c2021-09-08 14:05:16 +0200977 client2 = std::make_unique<TestClient>(
978 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, empty)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000979
980 SocketAddress addr4;
981 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
982 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
983 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
984
985 SocketAddress addr5;
986 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
987 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
988 EXPECT_EQ(addr5, addr1);
989
990 addr2 = addr4;
991 }
992}
993
994void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
995 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
996 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
997 // documentation.
998 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
Yves Gerey665174f2018-06-19 15:03:05 +0200999 std::string dest =
1000 (loopback.family() == AF_INET6) ? "2001:db8::1" : "192.0.2.0";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001001 SocketAddress test_addr(dest, 2345);
1002
1003 // Test send
Niels Möller50f7c2c2021-09-08 14:05:16 +02001004 auto client = std::make_unique<TestClient>(
1005 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, empty)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001006 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -07001007 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001008 // Init the test packet just to avoid memcheck warning.
1009 memset(test_packet.get(), 0, test_packet_size);
1010 // Set the send buffer size to the same size as the test packet to have a
1011 // better chance to get EWOULDBLOCK.
1012 int send_buffer_size = test_packet_size;
1013#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
1014 send_buffer_size /= 2;
1015#endif
1016 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
1017
1018 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001019 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001020 int sent_packet_num = 0;
1021 int expected_error = EWOULDBLOCK;
1022 while (start_ms + kTimeout > Time()) {
1023 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
1024 ++sent_packet_num;
1025 if (ret != test_packet_size) {
1026 error = client->GetError();
1027 if (error == expected_error) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001028 RTC_LOG(LS_INFO) << "Got expected error code after sending "
1029 << sent_packet_num << " packets.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001030 break;
1031 }
1032 }
1033 }
1034 EXPECT_EQ(expected_error, error);
1035 EXPECT_FALSE(client->ready_to_send());
1036 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
Mirko Bonadei675513b2017-11-09 11:09:25 +01001037 RTC_LOG(LS_INFO) << "Got SignalReadyToSend";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001038}
1039
1040void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
Niels Möllerd0b88792021-08-12 10:32:30 +02001041 std::unique_ptr<Socket> socket(
Niels Möller50f7c2c2021-09-08 14:05:16 +02001042 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001043 socket->Bind(SocketAddress(loopback, 0));
1044
1045 // Check SNDBUF/RCVBUF.
1046 const int desired_size = 12345;
1047#if defined(WEBRTC_LINUX)
1048 // Yes, really. It's in the kernel source.
1049 const int expected_size = desired_size * 2;
1050#else // !WEBRTC_LINUX
1051 const int expected_size = desired_size;
1052#endif // !WEBRTC_LINUX
1053 int recv_size = 0;
1054 int send_size = 0;
1055 // get the initial sizes
1056 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1057 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1058 // set our desired sizes
1059 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
1060 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
1061 // get the sizes again
1062 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1063 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1064 // make sure they are right
1065 ASSERT_EQ(expected_size, recv_size);
1066 ASSERT_EQ(expected_size, send_size);
1067
1068 // Check that we can't set NODELAY on a UDP socket.
1069 int current_nd, desired_nd = 1;
1070 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1071 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -08001072
1073#if defined(WEBRTC_POSIX)
1074 // Check DSCP.
1075 int current_dscp, desired_dscp = 1;
1076 ASSERT_NE(-1, socket->GetOption(Socket::OPT_DSCP, &current_dscp));
1077 ASSERT_NE(-1, socket->SetOption(Socket::OPT_DSCP, desired_dscp));
1078 ASSERT_NE(-1, socket->GetOption(Socket::OPT_DSCP, &current_dscp));
1079 ASSERT_EQ(desired_dscp, current_dscp);
1080#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001081}
1082
Stefan Holmer9131efd2016-05-23 18:19:26 +02001083void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001084 StreamSink sink;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001085 std::unique_ptr<Socket> socket(
Niels Möller50f7c2c2021-09-08 14:05:16 +02001086 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
Stefan Holmer9131efd2016-05-23 18:19:26 +02001087 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1088 SocketAddress address = socket->GetLocalAddress();
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001089 sink.Monitor(socket.get());
Stefan Holmer9131efd2016-05-23 18:19:26 +02001090
nissedeb95f32016-11-28 01:54:54 -08001091 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001092 socket->SendTo("foo", 3, address);
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001093
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001094 int64_t recv_timestamp_1;
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001095 // Wait until data is available.
1096 EXPECT_TRUE_WAIT(sink.Check(socket.get(), SSE_READ), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001097 char buffer[3];
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001098 ASSERT_GT(socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1), 0);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001099
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001100 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001101 Thread::SleepMs(kTimeBetweenPacketsMs);
1102
nissedeb95f32016-11-28 01:54:54 -08001103 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001104 socket->SendTo("bar", 3, address);
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001105 // Wait until data is available.
1106 EXPECT_TRUE_WAIT(sink.Check(socket.get(), SSE_READ), kTimeout);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001107 int64_t recv_timestamp_2;
Per Kjellanderfdcfefa2022-11-08 12:48:52 +01001108 ASSERT_GT(socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2), 0);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001109
1110 int64_t system_time_diff = send_time_2 - send_time_1;
1111 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1112 // Compare against the system time at the point of sending, because
1113 // SleepMs may not sleep for exactly the requested time.
1114 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001115}
1116
Per Kjellander3daf6962022-11-08 18:23:43 +01001117void SocketTest::UdpSocketRecvTimestampUseRtcEpoch(const IPAddress& loopback) {
1118 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
1119 std::unique_ptr<Socket> socket(
1120 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
1121 ASSERT_EQ(socket->Bind(SocketAddress(loopback, 0)), 0);
1122 SocketAddress address = socket->GetLocalAddress();
1123 socket = nullptr;
1124
1125 auto client1 = std::make_unique<TestClient>(
1126 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, address)));
1127 auto client2 = std::make_unique<TestClient>(
1128 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, empty)));
1129
1130 SocketAddress addr2;
1131 client2->SendTo("foo", 3, address);
1132 std::unique_ptr<TestClient::Packet> packet_1 = client1->NextPacket(10000);
1133 ASSERT_TRUE(packet_1 != nullptr);
1134 EXPECT_NEAR(packet_1->packet_time_us, rtc::TimeMicros(), 1000'000);
1135
1136 Thread::SleepMs(100);
1137 client2->SendTo("bar", 3, address);
1138 std::unique_ptr<TestClient::Packet> packet_2 = client1->NextPacket(10000);
1139 ASSERT_TRUE(packet_2 != nullptr);
1140 EXPECT_GT(packet_2->packet_time_us, packet_1->packet_time_us);
1141 EXPECT_NEAR(packet_2->packet_time_us, rtc::TimeMicros(), 1000'000);
1142}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001143} // namespace rtc