blob: 01a2bed26d9e4a85d88a0eafaf43cf2b25ecd5b8 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2007 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "rtc_base/socket.h"
12
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <errno.h>
14#include <stdint.h>
15#include <string.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020016
jbauch555604a2016-04-26 03:13:22 -070017#include <memory>
18
Karl Wiberg918f50c2018-07-05 11:40:33 +020019#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "rtc_base/async_packet_socket.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "rtc_base/async_udp_socket.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "rtc_base/buffer.h"
24#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 16:47:49 +010025#include "rtc_base/location.h"
26#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080027#include "rtc_base/message_handler.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/net_helpers.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "rtc_base/socket_address.h"
30#include "rtc_base/socket_server.h"
Yves Gerey3e707812018-11-28 16:47:49 +010031#include "rtc_base/socket_unittest.h"
Steve Anton10542f22019-01-11 09:11:00 -080032#include "rtc_base/test_client.h"
33#include "rtc_base/test_utils.h"
Yves Gerey3e707812018-11-28 16:47:49 +010034#include "rtc_base/third_party/sigslot/sigslot.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020035#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080036#include "rtc_base/time_utils.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000037
38namespace rtc {
39
kwibergd0d81482017-04-18 03:18:22 -070040using webrtc::testing::SSE_CLOSE;
41using webrtc::testing::SSE_ERROR;
42using webrtc::testing::SSE_OPEN;
43using webrtc::testing::SSE_READ;
44using webrtc::testing::SSE_WRITE;
45using webrtc::testing::StreamSink;
46
Mirko Bonadei675513b2017-11-09 11:09:25 +010047#define MAYBE_SKIP_IPV6 \
48 if (!HasIPv6Enabled()) { \
49 RTC_LOG(LS_INFO) << "No IPv6... skipping"; \
50 return; \
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000051 }
52
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070053// Data size to be used in TcpInternal tests.
54static const size_t kTcpInternalDataSize = 1024 * 1024; // bytes
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000055
56void SocketTest::TestConnectIPv4() {
57 ConnectInternal(kIPv4Loopback);
58}
59
60void SocketTest::TestConnectIPv6() {
61 MAYBE_SKIP_IPV6;
62 ConnectInternal(kIPv6Loopback);
63}
64
65void SocketTest::TestConnectWithDnsLookupIPv4() {
66 ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
67}
68
69void SocketTest::TestConnectWithDnsLookupIPv6() {
70 // TODO: Enable this when DNS resolution supports IPv6.
Mirko Bonadei675513b2017-11-09 11:09:25 +010071 RTC_LOG(LS_INFO) << "Skipping IPv6 DNS test";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000072 // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
73}
74
75void SocketTest::TestConnectFailIPv4() {
76 ConnectFailInternal(kIPv4Loopback);
77}
78
79void SocketTest::TestConnectFailIPv6() {
80 MAYBE_SKIP_IPV6;
81 ConnectFailInternal(kIPv6Loopback);
82}
83
84void SocketTest::TestConnectWithDnsLookupFailIPv4() {
85 ConnectWithDnsLookupFailInternal(kIPv4Loopback);
86}
87
88void SocketTest::TestConnectWithDnsLookupFailIPv6() {
89 MAYBE_SKIP_IPV6;
90 ConnectWithDnsLookupFailInternal(kIPv6Loopback);
91}
92
93void SocketTest::TestConnectWithClosedSocketIPv4() {
94 ConnectWithClosedSocketInternal(kIPv4Loopback);
95}
96
97void SocketTest::TestConnectWithClosedSocketIPv6() {
98 MAYBE_SKIP_IPV6;
99 ConnectWithClosedSocketInternal(kIPv6Loopback);
100}
101
102void SocketTest::TestConnectWhileNotClosedIPv4() {
103 ConnectWhileNotClosedInternal(kIPv4Loopback);
104}
105
106void SocketTest::TestConnectWhileNotClosedIPv6() {
107 MAYBE_SKIP_IPV6;
108 ConnectWhileNotClosedInternal(kIPv6Loopback);
109}
110
111void SocketTest::TestServerCloseDuringConnectIPv4() {
112 ServerCloseDuringConnectInternal(kIPv4Loopback);
113}
114
115void SocketTest::TestServerCloseDuringConnectIPv6() {
116 MAYBE_SKIP_IPV6;
117 ServerCloseDuringConnectInternal(kIPv6Loopback);
118}
119
120void SocketTest::TestClientCloseDuringConnectIPv4() {
121 ClientCloseDuringConnectInternal(kIPv4Loopback);
122}
123
124void SocketTest::TestClientCloseDuringConnectIPv6() {
125 MAYBE_SKIP_IPV6;
126 ClientCloseDuringConnectInternal(kIPv6Loopback);
127}
128
129void SocketTest::TestServerCloseIPv4() {
130 ServerCloseInternal(kIPv4Loopback);
131}
132
133void SocketTest::TestServerCloseIPv6() {
134 MAYBE_SKIP_IPV6;
135 ServerCloseInternal(kIPv6Loopback);
136}
137
138void SocketTest::TestCloseInClosedCallbackIPv4() {
139 CloseInClosedCallbackInternal(kIPv4Loopback);
140}
141
142void SocketTest::TestCloseInClosedCallbackIPv6() {
143 MAYBE_SKIP_IPV6;
144 CloseInClosedCallbackInternal(kIPv6Loopback);
145}
146
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000147void SocketTest::TestDeleteInReadCallbackIPv4() {
148 DeleteInReadCallbackInternal(kIPv4Loopback);
149}
150
151void SocketTest::TestDeleteInReadCallbackIPv6() {
152 MAYBE_SKIP_IPV6;
153 DeleteInReadCallbackInternal(kIPv6Loopback);
154}
155
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000156void SocketTest::TestSocketServerWaitIPv4() {
157 SocketServerWaitInternal(kIPv4Loopback);
158}
159
160void SocketTest::TestSocketServerWaitIPv6() {
161 MAYBE_SKIP_IPV6;
162 SocketServerWaitInternal(kIPv6Loopback);
163}
164
165void SocketTest::TestTcpIPv4() {
jbauchf2a2bf42016-02-03 16:45:32 -0800166 TcpInternal(kIPv4Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000167}
168
169void SocketTest::TestTcpIPv6() {
170 MAYBE_SKIP_IPV6;
jbauchf2a2bf42016-02-03 16:45:32 -0800171 TcpInternal(kIPv6Loopback, kTcpInternalDataSize, -1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000172}
173
174void SocketTest::TestSingleFlowControlCallbackIPv4() {
175 SingleFlowControlCallbackInternal(kIPv4Loopback);
176}
177
178void SocketTest::TestSingleFlowControlCallbackIPv6() {
179 MAYBE_SKIP_IPV6;
180 SingleFlowControlCallbackInternal(kIPv6Loopback);
181}
182
183void SocketTest::TestUdpIPv4() {
184 UdpInternal(kIPv4Loopback);
185}
186
187void SocketTest::TestUdpIPv6() {
188 MAYBE_SKIP_IPV6;
189 UdpInternal(kIPv6Loopback);
190}
191
192void SocketTest::TestUdpReadyToSendIPv4() {
193#if !defined(WEBRTC_MAC)
194 // TODO(ronghuawu): Enable this test on mac/ios.
195 UdpReadyToSend(kIPv4Loopback);
196#endif
197}
198
199void SocketTest::TestUdpReadyToSendIPv6() {
200#if defined(WEBRTC_WIN)
201 // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
202 MAYBE_SKIP_IPV6;
203 UdpReadyToSend(kIPv6Loopback);
204#endif
205}
206
207void SocketTest::TestGetSetOptionsIPv4() {
208 GetSetOptionsInternal(kIPv4Loopback);
209}
210
211void SocketTest::TestGetSetOptionsIPv6() {
212 MAYBE_SKIP_IPV6;
213 GetSetOptionsInternal(kIPv6Loopback);
214}
215
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700216void SocketTest::TestSocketRecvTimestampIPv4() {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200217 SocketRecvTimestamp(kIPv4Loopback);
218}
219
Taylor Brandstetter6f825352016-08-11 15:38:28 -0700220void SocketTest::TestSocketRecvTimestampIPv6() {
221 MAYBE_SKIP_IPV6;
222 SocketRecvTimestamp(kIPv6Loopback);
223}
224
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000225// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
226// values on Windows, but an empty address of the same family on Linux/MacOS X.
227bool IsUnspecOrEmptyIP(const IPAddress& address) {
228#if !defined(WEBRTC_WIN)
229 return IPIsAny(address);
230#else
231 return address.family() == AF_UNSPEC;
232#endif
233}
234
235void SocketTest::ConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700236 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000237 SocketAddress accept_addr;
238
239 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200240 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200241 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000242 sink.Monitor(client.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200243 EXPECT_EQ(Socket::CS_CLOSED, client->GetState());
Jonas Olssonabbe8412018-04-03 13:40:05 +0200244 EXPECT_TRUE(IsUnspecOrEmptyIP(client->GetLocalAddress().ipaddr()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000245
246 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200247 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200248 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000249 sink.Monitor(server.get());
250 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
251 EXPECT_EQ(0, server->Listen(5));
Niels Möllerd0b88792021-08-12 10:32:30 +0200252 EXPECT_EQ(Socket::CS_CONNECTING, server->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000253
254 // Ensure no pending server connections, since we haven't done anything yet.
kwibergd0d81482017-04-18 03:18:22 -0700255 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800256 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000257 EXPECT_TRUE(accept_addr.IsNil());
258
259 // Attempt connect to listening socket.
260 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
261 EXPECT_FALSE(client->GetLocalAddress().IsNil());
262 EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
263
264 // Client is connecting, outcome not yet determined.
Niels Möllerd0b88792021-08-12 10:32:30 +0200265 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700266 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
267 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000268
269 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700270 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200271 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000272 ASSERT_TRUE(accepted);
273 EXPECT_FALSE(accept_addr.IsNil());
274 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
275
276 // Connected from server perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200277 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000278 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
279 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
280
281 // Connected from client perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200282 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700283 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
284 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000285 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
286 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
287}
288
289void SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
290 const std::string& host) {
kwibergd0d81482017-04-18 03:18:22 -0700291 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000292 SocketAddress accept_addr;
293
294 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200295 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200296 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000297 sink.Monitor(client.get());
298
299 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200300 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200301 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000302 sink.Monitor(server.get());
303 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
304 EXPECT_EQ(0, server->Listen(5));
305
306 // Attempt connect to listening socket.
307 SocketAddress dns_addr(server->GetLocalAddress());
308 dns_addr.SetIP(host);
309 EXPECT_EQ(0, client->Connect(dns_addr));
310 // TODO: Bind when doing DNS lookup.
Yves Gerey665174f2018-06-19 15:03:05 +0200311 // EXPECT_NE(kEmptyAddr, client->GetLocalAddress()); // Implicit Bind
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000312
313 // Client is connecting, outcome not yet determined.
Niels Möllerd0b88792021-08-12 10:32:30 +0200314 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
kwibergd0d81482017-04-18 03:18:22 -0700315 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
316 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000317
318 // Server has pending connection, accept it.
kwibergd0d81482017-04-18 03:18:22 -0700319 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200320 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000321 ASSERT_TRUE(accepted);
322 EXPECT_FALSE(accept_addr.IsNil());
323 EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
324
325 // Connected from server perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200326 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000327 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
328 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
329
330 // Connected from client perspective, check the addresses are correct.
Niels Möllerd0b88792021-08-12 10:32:30 +0200331 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700332 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
333 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000334 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
335 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
336}
337
338void SocketTest::ConnectFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700339 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000340 SocketAddress accept_addr;
341
342 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200343 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200344 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000345 sink.Monitor(client.get());
346
347 // Create server, but don't listen yet.
Niels Möllerd0b88792021-08-12 10:32:30 +0200348 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200349 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000350 sink.Monitor(server.get());
351 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
352
353 // Attempt connect to a non-existent socket.
354 // We don't connect to the server socket created above, since on
355 // MacOS it takes about 75 seconds to get back an error!
356 SocketAddress bogus_addr(loopback, 65535);
357 EXPECT_EQ(0, client->Connect(bogus_addr));
358
359 // Wait for connection to fail (ECONNREFUSED).
Niels Möllerd0b88792021-08-12 10:32:30 +0200360 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700361 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
362 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000363 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
364
365 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700366 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800367 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000368 EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
369}
370
371void SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700372 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000373 SocketAddress accept_addr;
374
375 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200376 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200377 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000378 sink.Monitor(client.get());
379
380 // Create server, but don't listen yet.
Niels Möllerd0b88792021-08-12 10:32:30 +0200381 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200382 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000383 sink.Monitor(server.get());
384 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
385
386 // Attempt connect to a non-existent host.
387 // We don't connect to the server socket created above, since on
388 // MacOS it takes about 75 seconds to get back an error!
389 SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
390 EXPECT_EQ(0, client->Connect(bogus_dns_addr));
391
392 // Wait for connection to fail (EHOSTNOTFOUND).
393 bool dns_lookup_finished = false;
Niels Möllerd0b88792021-08-12 10:32:30 +0200394 WAIT_(client->GetState() == Socket::CS_CLOSED, kTimeout, dns_lookup_finished);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000395 if (!dns_lookup_finished) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100396 RTC_LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
Jonas Olssonb2b20312020-01-14 12:11:31 +0100397 "seconds.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000398 return;
399 }
400
Niels Möllerd0b88792021-08-12 10:32:30 +0200401 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700402 EXPECT_FALSE(sink.Check(client.get(), SSE_OPEN));
403 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000404 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
405 // Should be no pending server connections.
kwibergd0d81482017-04-18 03:18:22 -0700406 EXPECT_FALSE(sink.Check(server.get(), SSE_READ));
deadbeef37f5ecf2017-02-27 14:06:41 -0800407 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000408 EXPECT_TRUE(accept_addr.IsNil());
409}
410
411void SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
412 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200413 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200414 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000415 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
416 EXPECT_EQ(0, server->Listen(5));
417
418 // Create a client and put in to CS_CLOSED state.
Niels Möllerd0b88792021-08-12 10:32:30 +0200419 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200420 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000421 EXPECT_EQ(0, client->Close());
Niels Möllerd0b88792021-08-12 10:32:30 +0200422 EXPECT_EQ(Socket::CS_CLOSED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000423
424 // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
425 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200426 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000427}
428
429void SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
430 // Create server and listen.
kwibergd0d81482017-04-18 03:18:22 -0700431 StreamSink sink;
Niels Möllerd0b88792021-08-12 10:32:30 +0200432 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200433 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000434 sink.Monitor(server.get());
435 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
436 EXPECT_EQ(0, server->Listen(5));
437 // Create client, connect.
Niels Möllerd0b88792021-08-12 10:32:30 +0200438 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200439 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000440 EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200441 EXPECT_EQ(Socket::CS_CONNECTING, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000442 // Try to connect again. Should fail, but not interfere with original attempt.
443 EXPECT_EQ(SOCKET_ERROR,
444 client->Connect(SocketAddress(server->GetLocalAddress())));
445
446 // Accept the original connection.
447 SocketAddress accept_addr;
kwibergd0d81482017-04-18 03:18:22 -0700448 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200449 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000450 ASSERT_TRUE(accepted);
451 EXPECT_FALSE(accept_addr.IsNil());
452
453 // Check the states and addresses.
Niels Möllerd0b88792021-08-12 10:32:30 +0200454 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000455 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
456 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
Niels Möllerd0b88792021-08-12 10:32:30 +0200457 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000458 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
459 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
460
461 // Try to connect again, to an unresolved hostname.
462 // Shouldn't break anything.
Yves Gerey665174f2018-06-19 15:03:05 +0200463 EXPECT_EQ(SOCKET_ERROR, client->Connect(SocketAddress(
464 "localhost", server->GetLocalAddress().port())));
Niels Möllerd0b88792021-08-12 10:32:30 +0200465 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
466 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000467 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
468 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
469}
470
471void SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700472 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000473
474 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200475 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200476 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000477 sink.Monitor(client.get());
478
479 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200480 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200481 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000482 sink.Monitor(server.get());
483 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
484 EXPECT_EQ(0, server->Listen(5));
485
486 // Attempt connect to listening socket.
487 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
488
489 // Close down the server while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700490 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000491 server->Close();
492
493 // This should fail the connection for the client. Clean up.
Niels Möllerd0b88792021-08-12 10:32:30 +0200494 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700495 EXPECT_TRUE(sink.Check(client.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000496 client->Close();
497}
498
499void SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700500 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000501 SocketAddress accept_addr;
502
503 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200504 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200505 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000506 sink.Monitor(client.get());
507
508 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200509 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200510 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000511 sink.Monitor(server.get());
512 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
513 EXPECT_EQ(0, server->Listen(5));
514
515 // Attempt connect to listening socket.
516 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
517
518 // Close down the client while the socket is in the accept queue.
kwibergd0d81482017-04-18 03:18:22 -0700519 EXPECT_TRUE_WAIT(sink.Check(server.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000520 client->Close();
521
522 // The connection should still be able to be accepted.
Niels Möllerd0b88792021-08-12 10:32:30 +0200523 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000524 ASSERT_TRUE(accepted);
525 sink.Monitor(accepted.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200526 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000527
528 // The accepted socket should then close (possibly with err, timing-related)
Niels Möllerd0b88792021-08-12 10:32:30 +0200529 EXPECT_EQ_WAIT(Socket::CS_CLOSED, accepted->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700530 EXPECT_TRUE(sink.Check(accepted.get(), SSE_CLOSE) ||
531 sink.Check(accepted.get(), SSE_ERROR));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000532
533 // The client should not get a close event.
kwibergd0d81482017-04-18 03:18:22 -0700534 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000535}
536
537void SocketTest::ServerCloseInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700538 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000539 SocketAddress accept_addr;
540
541 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200542 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200543 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000544 sink.Monitor(client.get());
545
546 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200547 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200548 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000549 sink.Monitor(server.get());
550 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
551 EXPECT_EQ(0, server->Listen(5));
552
553 // Attempt connection.
554 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
555
556 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700557 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200558 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000559 ASSERT_TRUE(accepted);
560 sink.Monitor(accepted.get());
561
562 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200563 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700564 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000565 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
566 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
567
568 // Send data to the client, and then close the connection.
569 EXPECT_EQ(1, accepted->Send("a", 1));
570 accepted->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200571 EXPECT_EQ(Socket::CS_CLOSED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000572
573 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700574 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
575 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
Niels Möllerd0b88792021-08-12 10:32:30 +0200576 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000577
578 // Ensure the data can be read.
579 char buffer[10];
Stefan Holmer9131efd2016-05-23 18:19:26 +0200580 EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer), nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000581 EXPECT_EQ('a', buffer[0]);
582
583 // Now we should close, but the remote address will remain.
Niels Möllerd0b88792021-08-12 10:32:30 +0200584 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700585 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000586 EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
587
588 // The closer should not get a close signal.
kwibergd0d81482017-04-18 03:18:22 -0700589 EXPECT_FALSE(sink.Check(accepted.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000590 EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
591
592 // And the closee should only get a single signal.
593 Thread::Current()->ProcessMessages(0);
kwibergd0d81482017-04-18 03:18:22 -0700594 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000595
596 // Close down the client and ensure all is good.
597 client->Close();
kwibergd0d81482017-04-18 03:18:22 -0700598 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000599 EXPECT_TRUE(client->GetRemoteAddress().IsNil());
600}
601
602class SocketCloser : public sigslot::has_slots<> {
603 public:
Niels Möllerd0b88792021-08-12 10:32:30 +0200604 void OnClose(Socket* socket, int error) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000605 socket->Close(); // Deleting here would blow up the vector of handlers
606 // for the socket's signal.
607 }
608};
609
610void SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700611 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000612 SocketCloser closer;
613 SocketAddress accept_addr;
614
615 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200616 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200617 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000618 sink.Monitor(client.get());
619 client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
620
621 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200622 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200623 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000624 sink.Monitor(server.get());
625 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
626 EXPECT_EQ(0, server->Listen(5));
627
628 // Attempt connection.
629 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
630
631 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700632 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200633 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000634 ASSERT_TRUE(accepted);
635 sink.Monitor(accepted.get());
636
637 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200638 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700639 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000640 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
641 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
642
643 // Send data to the client, and then close the connection.
644 accepted->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200645 EXPECT_EQ(Socket::CS_CLOSED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000646
647 // Expect that the client is notified, and has not yet closed.
kwibergd0d81482017-04-18 03:18:22 -0700648 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
Niels Möllerd0b88792021-08-12 10:32:30 +0200649 EXPECT_EQ(Socket::CS_CONNECTED, client->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000650
651 // Now we should be closed and invalidated
Niels Möllerd0b88792021-08-12 10:32:30 +0200652 EXPECT_EQ_WAIT(Socket::CS_CLOSED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700653 EXPECT_TRUE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000654 EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
655}
656
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000657// Helper class specifically for the test below.
658class SocketDeleter : public sigslot::has_slots<> {
659 public:
Niels Möllerd0b88792021-08-12 10:32:30 +0200660 explicit SocketDeleter(std::unique_ptr<Socket> socket)
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000661 : socket_(std::move(socket)) {}
662
Niels Möllerd0b88792021-08-12 10:32:30 +0200663 void Delete(Socket* other) { socket_.reset(); }
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000664
665 bool deleted() const { return socket_ == nullptr; }
666
667 private:
Niels Möllerd0b88792021-08-12 10:32:30 +0200668 std::unique_ptr<Socket> socket_;
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000669};
670
671// Tested deleting a socket within another socket's read callback. A previous
672// iteration of the select loop failed in this situation, if both sockets
673// became readable at the same time.
674void SocketTest::DeleteInReadCallbackInternal(const IPAddress& loopback) {
Niels Möllerd0b88792021-08-12 10:32:30 +0200675 std::unique_ptr<Socket> socket1(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200676 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
Niels Möllerd0b88792021-08-12 10:32:30 +0200677 std::unique_ptr<Socket> socket2(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200678 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000679 EXPECT_EQ(0, socket1->Bind(SocketAddress(loopback, 0)));
680 EXPECT_EQ(0, socket2->Bind(SocketAddress(loopback, 0)));
681 EXPECT_EQ(3, socket1->SendTo("foo", 3, socket1->GetLocalAddress()));
682 EXPECT_EQ(3, socket2->SendTo("bar", 3, socket1->GetLocalAddress()));
683 // Sleep a while to ensure sends are both completed at the same time.
684 Thread::SleepMs(1000);
685
686 // Configure the helper class to delete socket 2 when socket 1 has a read
687 // event.
688 SocketDeleter deleter(std::move(socket2));
689 socket1->SignalReadEvent.connect(&deleter, &SocketDeleter::Delete);
690 EXPECT_TRUE_WAIT(deleter.deleted(), kTimeout);
691}
692
Tomas Gunnarssonabdb4702020-09-05 18:43:36 +0200693class Sleeper : public MessageHandlerAutoCleanup {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000694 public:
Steve Anton9de3aac2017-10-24 10:08:26 -0700695 void OnMessage(Message* msg) override { Thread::Current()->SleepMs(500); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000696};
697
698void SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700699 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000700 SocketAddress accept_addr;
701
702 // Create & connect server and client sockets.
Niels Möllerd0b88792021-08-12 10:32:30 +0200703 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200704 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
Niels Möllerd0b88792021-08-12 10:32:30 +0200705 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200706 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000707 sink.Monitor(client.get());
708 sink.Monitor(server.get());
709 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
710 EXPECT_EQ(0, server->Listen(5));
711
712 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
kwibergd0d81482017-04-18 03:18:22 -0700713 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000714
Niels Möllerd0b88792021-08-12 10:32:30 +0200715 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000716 ASSERT_TRUE(accepted);
717 sink.Monitor(accepted.get());
Niels Möllerd0b88792021-08-12 10:32:30 +0200718 EXPECT_EQ(Socket::CS_CONNECTED, accepted->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000719 EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
720 EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
721
Niels Möllerd0b88792021-08-12 10:32:30 +0200722 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700723 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
724 EXPECT_FALSE(sink.Check(client.get(), SSE_CLOSE));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000725 EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
726 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
727
728 // Do an i/o operation, triggering an eventual callback.
kwibergd0d81482017-04-18 03:18:22 -0700729 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000730 char buf[1024] = {0};
731
732 EXPECT_EQ(1024, client->Send(buf, 1024));
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 // Shouldn't signal when blocked in a thread Send, where process_io is false.
tommie7251592017-07-14 14:44:46 -0700736 std::unique_ptr<Thread> thread(Thread::CreateWithSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000737 thread->Start();
738 Sleeper sleeper;
Niels Möllerd0b88792021-08-12 10:32:30 +0200739 TypedMessageData<Socket*> data(client.get());
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700740 thread->Send(RTC_FROM_HERE, &sleeper, 0, &data);
kwibergd0d81482017-04-18 03:18:22 -0700741 EXPECT_FALSE(sink.Check(accepted.get(), SSE_READ));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000742
743 // But should signal when process_io is true.
kwibergd0d81482017-04-18 03:18:22 -0700744 EXPECT_TRUE_WAIT((sink.Check(accepted.get(), SSE_READ)), kTimeout);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200745 EXPECT_LT(0, accepted->Recv(buf, 1024, nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000746}
747
Yves Gerey665174f2018-06-19 15:03:05 +0200748void SocketTest::TcpInternal(const IPAddress& loopback,
749 size_t data_size,
750 ptrdiff_t max_send_size) {
kwibergd0d81482017-04-18 03:18:22 -0700751 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000752 SocketAddress accept_addr;
753
jbauchf2a2bf42016-02-03 16:45:32 -0800754 // Create receiving client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200755 std::unique_ptr<Socket> receiver(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200756 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
jbauchf2a2bf42016-02-03 16:45:32 -0800757 sink.Monitor(receiver.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000758
759 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200760 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200761 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000762 sink.Monitor(server.get());
763 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
764 EXPECT_EQ(0, server->Listen(5));
765
766 // Attempt connection.
jbauchf2a2bf42016-02-03 16:45:32 -0800767 EXPECT_EQ(0, receiver->Connect(server->GetLocalAddress()));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000768
jbauchf2a2bf42016-02-03 16:45:32 -0800769 // Accept connection which will be used for sending.
kwibergd0d81482017-04-18 03:18:22 -0700770 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200771 std::unique_ptr<Socket> sender(server->Accept(&accept_addr));
jbauchf2a2bf42016-02-03 16:45:32 -0800772 ASSERT_TRUE(sender);
773 sink.Monitor(sender.get());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000774
775 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200776 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700777 EXPECT_TRUE(sink.Check(receiver.get(), SSE_OPEN));
jbauchf2a2bf42016-02-03 16:45:32 -0800778 EXPECT_EQ(receiver->GetRemoteAddress(), sender->GetLocalAddress());
779 EXPECT_EQ(sender->GetRemoteAddress(), receiver->GetLocalAddress());
780
781 // Create test data.
782 rtc::Buffer send_buffer(0, data_size);
783 rtc::Buffer recv_buffer(0, data_size);
784 for (size_t i = 0; i < data_size; ++i) {
785 char ch = static_cast<char>(i % 256);
786 send_buffer.AppendData(&ch, sizeof(ch));
787 }
danilchapb7b9dca2016-08-05 05:55:43 -0700788 rtc::Buffer recved_data(0, data_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000789
790 // Send and receive a bunch of data.
jbauchf2a2bf42016-02-03 16:45:32 -0800791 size_t sent_size = 0;
792 bool writable = true;
793 bool send_called = false;
794 bool readable = false;
795 bool recv_called = false;
796 while (recv_buffer.size() < send_buffer.size()) {
797 // Send as much as we can while we're cleared to send.
798 while (writable && sent_size < send_buffer.size()) {
799 int unsent_size = static_cast<int>(send_buffer.size() - sent_size);
800 int sent = sender->Send(send_buffer.data() + sent_size, unsent_size);
801 if (!send_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000802 // The first Send() after connecting or getting writability should
803 // succeed and send some data.
804 EXPECT_GT(sent, 0);
jbauchf2a2bf42016-02-03 16:45:32 -0800805 send_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000806 }
807 if (sent >= 0) {
jbauchf2a2bf42016-02-03 16:45:32 -0800808 EXPECT_LE(sent, unsent_size);
809 sent_size += sent;
810 if (max_send_size >= 0) {
danilchapb7b9dca2016-08-05 05:55:43 -0700811 EXPECT_LE(static_cast<ptrdiff_t>(sent), max_send_size);
jbauchf2a2bf42016-02-03 16:45:32 -0800812 if (sent < unsent_size) {
813 // If max_send_size is limiting the amount to send per call such
814 // that the sent amount is less than the unsent amount, we simulate
815 // that the socket is no longer writable.
816 writable = false;
817 }
818 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000819 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800820 ASSERT_TRUE(sender->IsBlocking());
821 writable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000822 }
823 }
824
825 // Read all the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800826 while (recv_buffer.size() < sent_size) {
827 if (!readable) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000828 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700829 EXPECT_TRUE_WAIT(sink.Check(receiver.get(), SSE_READ), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800830 readable = true;
831 recv_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000832 }
833
834 // Receive as much as we can get in a single recv call.
danilchapb7b9dca2016-08-05 05:55:43 -0700835 int recved_size = receiver->Recv(recved_data.data(), data_size, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000836
jbauchf2a2bf42016-02-03 16:45:32 -0800837 if (!recv_called) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000838 // The first Recv() after getting readability should succeed and receive
839 // some data.
840 // TODO: The following line is disabled due to flakey pulse
841 // builds. Re-enable if/when possible.
jbauchf2a2bf42016-02-03 16:45:32 -0800842 // EXPECT_GT(recved_size, 0);
843 recv_called = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000844 }
jbauchf2a2bf42016-02-03 16:45:32 -0800845 if (recved_size >= 0) {
846 EXPECT_LE(static_cast<size_t>(recved_size),
Yves Gerey665174f2018-06-19 15:03:05 +0200847 sent_size - recv_buffer.size());
danilchapb7b9dca2016-08-05 05:55:43 -0700848 recv_buffer.AppendData(recved_data.data(), recved_size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000849 } else {
jbauchf2a2bf42016-02-03 16:45:32 -0800850 ASSERT_TRUE(receiver->IsBlocking());
851 readable = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000852 }
853 }
854
jbauchf2a2bf42016-02-03 16:45:32 -0800855 // Once all that we've sent has been received, expect to be able to send
856 // again.
857 if (!writable) {
kwibergd0d81482017-04-18 03:18:22 -0700858 ASSERT_TRUE_WAIT(sink.Check(sender.get(), SSE_WRITE), kTimeout);
jbauchf2a2bf42016-02-03 16:45:32 -0800859 writable = true;
860 send_called = false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000861 }
862 }
863
864 // The received data matches the sent data.
jbauchf2a2bf42016-02-03 16:45:32 -0800865 EXPECT_EQ(data_size, sent_size);
866 EXPECT_EQ(data_size, recv_buffer.size());
867 EXPECT_EQ(recv_buffer, send_buffer);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000868
869 // Close down.
jbauchf2a2bf42016-02-03 16:45:32 -0800870 sender->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200871 EXPECT_EQ_WAIT(Socket::CS_CLOSED, receiver->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700872 EXPECT_TRUE(sink.Check(receiver.get(), SSE_CLOSE));
jbauchf2a2bf42016-02-03 16:45:32 -0800873 receiver->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000874}
875
876void SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
kwibergd0d81482017-04-18 03:18:22 -0700877 StreamSink sink;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000878 SocketAddress accept_addr;
879
880 // Create client.
Niels Möllerd0b88792021-08-12 10:32:30 +0200881 std::unique_ptr<Socket> client(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200882 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000883 sink.Monitor(client.get());
884
885 // Create server and listen.
Niels Möllerd0b88792021-08-12 10:32:30 +0200886 std::unique_ptr<Socket> server(
Niels Möller50f7c2c2021-09-08 14:05:16 +0200887 socket_factory_->CreateSocket(loopback.family(), SOCK_STREAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000888 sink.Monitor(server.get());
889 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
890 EXPECT_EQ(0, server->Listen(5));
891
892 // Attempt connection.
893 EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
894
895 // Accept connection.
kwibergd0d81482017-04-18 03:18:22 -0700896 EXPECT_TRUE_WAIT((sink.Check(server.get(), SSE_READ)), kTimeout);
Niels Möllerd0b88792021-08-12 10:32:30 +0200897 std::unique_ptr<Socket> accepted(server->Accept(&accept_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000898 ASSERT_TRUE(accepted);
899 sink.Monitor(accepted.get());
900
901 // Both sides are now connected.
Niels Möllerd0b88792021-08-12 10:32:30 +0200902 EXPECT_EQ_WAIT(Socket::CS_CONNECTED, client->GetState(), kTimeout);
kwibergd0d81482017-04-18 03:18:22 -0700903 EXPECT_TRUE(sink.Check(client.get(), SSE_OPEN));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000904 EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
905 EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
906
907 // Expect a writable callback from the connect.
kwibergd0d81482017-04-18 03:18:22 -0700908 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000909
910 // Fill the socket buffer.
911 char buf[1024 * 16] = {0};
912 int sends = 0;
Yves Gerey665174f2018-06-19 15:03:05 +0200913 while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {
914 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000915 EXPECT_TRUE(accepted->IsBlocking());
916
917 // Wait until data is available.
kwibergd0d81482017-04-18 03:18:22 -0700918 EXPECT_TRUE_WAIT(sink.Check(client.get(), SSE_READ), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000919
920 // Pull data.
921 for (int i = 0; i < sends; ++i) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200922 client->Recv(buf, arraysize(buf), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000923 }
924
925 // Expect at least one additional writable callback.
kwibergd0d81482017-04-18 03:18:22 -0700926 EXPECT_TRUE_WAIT(sink.Check(accepted.get(), SSE_WRITE), kTimeout);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000927
928 // Adding data in response to the writeable callback shouldn't cause infinite
929 // callbacks.
930 int extras = 0;
931 for (int i = 0; i < 100; ++i) {
tfarina5237aaf2015-11-10 23:44:30 -0800932 accepted->Send(&buf, arraysize(buf));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000933 rtc::Thread::Current()->ProcessMessages(1);
kwibergd0d81482017-04-18 03:18:22 -0700934 if (sink.Check(accepted.get(), SSE_WRITE)) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000935 extras++;
936 }
937 }
938 EXPECT_LT(extras, 2);
939
940 // Close down.
941 accepted->Close();
942 client->Close();
943}
944
945void SocketTest::UdpInternal(const IPAddress& loopback) {
946 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
947 // Test basic bind and connect behavior.
Niels Möller50f7c2c2021-09-08 14:05:16 +0200948 Socket* socket = socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM);
Niels Möllerd0b88792021-08-12 10:32:30 +0200949 EXPECT_EQ(Socket::CS_CLOSED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000950 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
951 SocketAddress addr1 = socket->GetLocalAddress();
952 EXPECT_EQ(0, socket->Connect(addr1));
Niels Möllerd0b88792021-08-12 10:32:30 +0200953 EXPECT_EQ(Socket::CS_CONNECTED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000954 socket->Close();
Niels Möllerd0b88792021-08-12 10:32:30 +0200955 EXPECT_EQ(Socket::CS_CLOSED, socket->GetState());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000956 delete socket;
957
958 // Test send/receive behavior.
Niels Möller50f7c2c2021-09-08 14:05:16 +0200959 auto client1 = std::make_unique<TestClient>(
960 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, addr1)));
961 auto client2 = std::make_unique<TestClient>(
962 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, empty)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000963
964 SocketAddress addr2;
965 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
966 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
967
968 SocketAddress addr3;
969 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
970 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
971 EXPECT_EQ(addr3, addr1);
972 // TODO: figure out what the intent is here
973 for (int i = 0; i < 10; ++i) {
Niels Möller50f7c2c2021-09-08 14:05:16 +0200974 client2 = std::make_unique<TestClient>(
975 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, empty)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000976
977 SocketAddress addr4;
978 EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
979 EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
980 EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
981
982 SocketAddress addr5;
983 EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
984 EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
985 EXPECT_EQ(addr5, addr1);
986
987 addr2 = addr4;
988 }
989}
990
991void SocketTest::UdpReadyToSend(const IPAddress& loopback) {
992 SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
993 // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
994 // documentation.
995 // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
Yves Gerey665174f2018-06-19 15:03:05 +0200996 std::string dest =
997 (loopback.family() == AF_INET6) ? "2001:db8::1" : "192.0.2.0";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000998 SocketAddress test_addr(dest, 2345);
999
1000 // Test send
Niels Möller50f7c2c2021-09-08 14:05:16 +02001001 auto client = std::make_unique<TestClient>(
1002 absl::WrapUnique(AsyncUDPSocket::Create(socket_factory_, empty)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001003 int test_packet_size = 1200;
jbauch555604a2016-04-26 03:13:22 -07001004 std::unique_ptr<char[]> test_packet(new char[test_packet_size]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001005 // Init the test packet just to avoid memcheck warning.
1006 memset(test_packet.get(), 0, test_packet_size);
1007 // Set the send buffer size to the same size as the test packet to have a
1008 // better chance to get EWOULDBLOCK.
1009 int send_buffer_size = test_packet_size;
1010#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
1011 send_buffer_size /= 2;
1012#endif
1013 client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
1014
1015 int error = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001016 uint32_t start_ms = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001017 int sent_packet_num = 0;
1018 int expected_error = EWOULDBLOCK;
1019 while (start_ms + kTimeout > Time()) {
1020 int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
1021 ++sent_packet_num;
1022 if (ret != test_packet_size) {
1023 error = client->GetError();
1024 if (error == expected_error) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001025 RTC_LOG(LS_INFO) << "Got expected error code after sending "
1026 << sent_packet_num << " packets.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001027 break;
1028 }
1029 }
1030 }
1031 EXPECT_EQ(expected_error, error);
1032 EXPECT_FALSE(client->ready_to_send());
1033 EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
Mirko Bonadei675513b2017-11-09 11:09:25 +01001034 RTC_LOG(LS_INFO) << "Got SignalReadyToSend";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001035}
1036
1037void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
Niels Möllerd0b88792021-08-12 10:32:30 +02001038 std::unique_ptr<Socket> socket(
Niels Möller50f7c2c2021-09-08 14:05:16 +02001039 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001040 socket->Bind(SocketAddress(loopback, 0));
1041
1042 // Check SNDBUF/RCVBUF.
1043 const int desired_size = 12345;
1044#if defined(WEBRTC_LINUX)
1045 // Yes, really. It's in the kernel source.
1046 const int expected_size = desired_size * 2;
1047#else // !WEBRTC_LINUX
1048 const int expected_size = desired_size;
1049#endif // !WEBRTC_LINUX
1050 int recv_size = 0;
1051 int send_size = 0;
1052 // get the initial sizes
1053 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1054 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1055 // set our desired sizes
1056 ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
1057 ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
1058 // get the sizes again
1059 ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
1060 ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
1061 // make sure they are right
1062 ASSERT_EQ(expected_size, recv_size);
1063 ASSERT_EQ(expected_size, send_size);
1064
1065 // Check that we can't set NODELAY on a UDP socket.
1066 int current_nd, desired_nd = 1;
1067 ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
1068 ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -08001069
1070#if defined(WEBRTC_POSIX)
1071 // Check DSCP.
1072 int current_dscp, desired_dscp = 1;
1073 ASSERT_NE(-1, socket->GetOption(Socket::OPT_DSCP, &current_dscp));
1074 ASSERT_NE(-1, socket->SetOption(Socket::OPT_DSCP, desired_dscp));
1075 ASSERT_NE(-1, socket->GetOption(Socket::OPT_DSCP, &current_dscp));
1076 ASSERT_EQ(desired_dscp, current_dscp);
1077#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001078}
1079
Stefan Holmer9131efd2016-05-23 18:19:26 +02001080void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {
1081 std::unique_ptr<Socket> socket(
Niels Möller50f7c2c2021-09-08 14:05:16 +02001082 socket_factory_->CreateSocket(loopback.family(), SOCK_DGRAM));
Stefan Holmer9131efd2016-05-23 18:19:26 +02001083 EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
1084 SocketAddress address = socket->GetLocalAddress();
1085
nissedeb95f32016-11-28 01:54:54 -08001086 int64_t send_time_1 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001087 socket->SendTo("foo", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001088 int64_t recv_timestamp_1;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001089 char buffer[3];
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001090 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1);
1091 EXPECT_GT(recv_timestamp_1, -1);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001092
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001093 const int64_t kTimeBetweenPacketsMs = 100;
Stefan Holmer9131efd2016-05-23 18:19:26 +02001094 Thread::SleepMs(kTimeBetweenPacketsMs);
1095
nissedeb95f32016-11-28 01:54:54 -08001096 int64_t send_time_2 = TimeMicros();
Stefan Holmer9131efd2016-05-23 18:19:26 +02001097 socket->SendTo("bar", 3, address);
Taylor Brandstetter6f825352016-08-11 15:38:28 -07001098 int64_t recv_timestamp_2;
1099 socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2);
1100
1101 int64_t system_time_diff = send_time_2 - send_time_1;
1102 int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1;
1103 // Compare against the system time at the point of sending, because
1104 // SleepMs may not sleep for exactly the requested time.
1105 EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000);
Stefan Holmer9131efd2016-05-23 18:19:26 +02001106}
1107
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001108} // namespace rtc