1 // Copyright 2022 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "quiche/quic/core/io/socket.h"
6
7 #include <string>
8
9 #include "absl/status/status.h"
10 #include "absl/status/statusor.h"
11 #include "absl/strings/string_view.h"
12 #include "absl/types/span.h"
13 #include "quiche/quic/platform/api/quic_ip_address.h"
14 #include "quiche/quic/platform/api/quic_ip_address_family.h"
15 #include "quiche/quic/platform/api/quic_socket_address.h"
16 #include "quiche/quic/test_tools/test_ip_packets.h"
17 #include "quiche/common/platform/api/quiche_logging.h"
18 #include "quiche/common/platform/api/quiche_test.h"
19 #include "quiche/common/platform/api/quiche_test_loopback.h"
20 #include "quiche/common/test_tools/quiche_test_utils.h"
21
22 namespace quic::test {
23 namespace {
24
25 using quiche::test::QuicheTest;
26 using quiche::test::StatusIs;
27 using testing::Lt;
28 using testing::SizeIs;
29
CreateTestSocket(socket_api::SocketProtocol protocol,bool blocking=true)30 SocketFd CreateTestSocket(socket_api::SocketProtocol protocol,
31 bool blocking = true) {
32 absl::StatusOr<SocketFd> socket = socket_api::CreateSocket(
33 quiche::TestLoopback().address_family(), protocol, blocking);
34
35 if (socket.ok()) {
36 return socket.value();
37 } else {
38 QUICHE_CHECK(false);
39 return kInvalidSocketFd;
40 }
41 }
42
CreateTestRawSocket(bool blocking=true,IpAddressFamily address_family=IpAddressFamily::IP_UNSPEC)43 SocketFd CreateTestRawSocket(
44 bool blocking = true,
45 IpAddressFamily address_family = IpAddressFamily::IP_UNSPEC) {
46 absl::StatusOr<SocketFd> socket;
47 switch (address_family) {
48 case IpAddressFamily::IP_V4:
49 socket = socket_api::CreateSocket(
50 quiche::TestLoopback4().address_family(),
51 socket_api::SocketProtocol::kRawIp, blocking);
52 break;
53 case IpAddressFamily::IP_V6:
54 socket = socket_api::CreateSocket(
55 quiche::TestLoopback6().address_family(),
56 socket_api::SocketProtocol::kRawIp, blocking);
57 break;
58 case IpAddressFamily::IP_UNSPEC:
59 socket = socket_api::CreateSocket(quiche::TestLoopback().address_family(),
60 socket_api::SocketProtocol::kRawIp,
61 blocking);
62 break;
63 }
64
65 if (socket.ok()) {
66 return socket.value();
67 } else {
68 // This is expected if test not run with relevant admin privileges or if
69 // address family is unsupported.
70 QUICHE_CHECK(absl::IsPermissionDenied(socket.status()) ||
71 absl::IsNotFound(socket.status()));
72 return kInvalidSocketFd;
73 }
74 }
75
TEST(SocketTest,CreateAndCloseSocket)76 TEST(SocketTest, CreateAndCloseSocket) {
77 QuicIpAddress localhost_address = quiche::TestLoopback();
78 absl::StatusOr<SocketFd> created_socket = socket_api::CreateSocket(
79 localhost_address.address_family(), socket_api::SocketProtocol::kUdp);
80
81 QUICHE_EXPECT_OK(created_socket.status());
82
83 QUICHE_EXPECT_OK(socket_api::Close(created_socket.value()));
84 }
85
TEST(SocketTest,CreateAndCloseRawSocket)86 TEST(SocketTest, CreateAndCloseRawSocket) {
87 QuicIpAddress localhost_address = quiche::TestLoopback();
88 absl::StatusOr<SocketFd> created_socket = socket_api::CreateSocket(
89 localhost_address.address_family(), socket_api::SocketProtocol::kRawIp);
90
91 // Raw IP socket creation will typically fail if not run with relevant admin
92 // privileges.
93 if (!created_socket.ok()) {
94 EXPECT_THAT(created_socket.status(),
95 StatusIs(absl::StatusCode::kPermissionDenied));
96 return;
97 }
98
99 QUICHE_EXPECT_OK(socket_api::Close(created_socket.value()));
100 }
101
TEST(SocketTest,SetSocketBlocking)102 TEST(SocketTest, SetSocketBlocking) {
103 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kUdp,
104 /*blocking=*/true);
105
106 QUICHE_EXPECT_OK(socket_api::SetSocketBlocking(socket, /*blocking=*/false));
107
108 QUICHE_EXPECT_OK(socket_api::Close(socket));
109 }
110
TEST(SocketTest,SetReceiveBufferSize)111 TEST(SocketTest, SetReceiveBufferSize) {
112 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kUdp,
113 /*blocking=*/true);
114
115 QUICHE_EXPECT_OK(socket_api::SetReceiveBufferSize(socket, /*size=*/100));
116
117 QUICHE_EXPECT_OK(socket_api::Close(socket));
118 }
119
TEST(SocketTest,SetSendBufferSize)120 TEST(SocketTest, SetSendBufferSize) {
121 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kUdp,
122 /*blocking=*/true);
123
124 QUICHE_EXPECT_OK(socket_api::SetSendBufferSize(socket, /*size=*/100));
125
126 QUICHE_EXPECT_OK(socket_api::Close(socket));
127 }
128
TEST(SocketTest,SetIpHeaderIncludedForRaw)129 TEST(SocketTest, SetIpHeaderIncludedForRaw) {
130 SocketFd socket =
131 CreateTestRawSocket(/*blocking=*/true, IpAddressFamily::IP_V4);
132 if (socket == kInvalidSocketFd) {
133 GTEST_SKIP();
134 }
135
136 QUICHE_EXPECT_OK(socket_api::SetIpHeaderIncluded(
137 socket, IpAddressFamily::IP_V4, /*ip_header_included=*/true));
138
139 QUICHE_EXPECT_OK(socket_api::Close(socket));
140 }
141
TEST(SocketTest,SetIpHeaderIncludedForRawV6)142 TEST(SocketTest, SetIpHeaderIncludedForRawV6) {
143 SocketFd socket =
144 CreateTestRawSocket(/*blocking=*/true, IpAddressFamily::IP_V6);
145 if (socket == kInvalidSocketFd) {
146 GTEST_SKIP();
147 }
148
149 QUICHE_EXPECT_OK(socket_api::SetIpHeaderIncluded(
150 socket, IpAddressFamily::IP_V6, /*ip_header_included=*/true));
151
152 QUICHE_EXPECT_OK(socket_api::Close(socket));
153 }
154
TEST(SocketTest,SetIpHeaderIncludedForUdp)155 TEST(SocketTest, SetIpHeaderIncludedForUdp) {
156 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kUdp,
157 /*blocking=*/true);
158
159 // Expect option only allowed for raw IP sockets.
160 EXPECT_THAT(socket_api::SetIpHeaderIncluded(socket, IpAddressFamily::IP_V4,
161 /*ip_header_included=*/true),
162 StatusIs(absl::StatusCode::kInvalidArgument));
163 EXPECT_THAT(socket_api::SetIpHeaderIncluded(socket, IpAddressFamily::IP_V6,
164 /*ip_header_included=*/true),
165 StatusIs(absl::StatusCode::kInvalidArgument));
166
167 QUICHE_EXPECT_OK(socket_api::Close(socket));
168 }
169
TEST(SocketTest,Connect)170 TEST(SocketTest, Connect) {
171 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kUdp);
172
173 // UDP, so "connecting" should succeed without any listening sockets.
174 QUICHE_EXPECT_OK(socket_api::Connect(
175 socket, QuicSocketAddress(quiche::TestLoopback(), /*port=*/0)));
176
177 QUICHE_EXPECT_OK(socket_api::Close(socket));
178 }
179
TEST(SocketTest,GetSocketError)180 TEST(SocketTest, GetSocketError) {
181 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kUdp,
182 /*blocking=*/true);
183
184 absl::Status error = socket_api::GetSocketError(socket);
185 QUICHE_EXPECT_OK(error);
186
187 QUICHE_EXPECT_OK(socket_api::Close(socket));
188 }
189
TEST(SocketTest,Bind)190 TEST(SocketTest, Bind) {
191 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kUdp);
192
193 QUICHE_EXPECT_OK(socket_api::Bind(
194 socket, QuicSocketAddress(quiche::TestLoopback(), /*port=*/0)));
195
196 QUICHE_EXPECT_OK(socket_api::Close(socket));
197 }
198
TEST(SocketTest,GetSocketAddress)199 TEST(SocketTest, GetSocketAddress) {
200 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kUdp);
201 QUICHE_ASSERT_OK(socket_api::Bind(
202 socket, QuicSocketAddress(quiche::TestLoopback(), /*port=*/0)));
203
204 absl::StatusOr<QuicSocketAddress> address =
205 socket_api::GetSocketAddress(socket);
206 QUICHE_EXPECT_OK(address);
207 EXPECT_TRUE(address.value().IsInitialized());
208 EXPECT_EQ(address.value().host(), quiche::TestLoopback());
209
210 QUICHE_EXPECT_OK(socket_api::Close(socket));
211 }
212
TEST(SocketTest,Listen)213 TEST(SocketTest, Listen) {
214 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kTcp);
215 QUICHE_ASSERT_OK(socket_api::Bind(
216 socket, QuicSocketAddress(quiche::TestLoopback(), /*port=*/0)));
217
218 QUICHE_EXPECT_OK(socket_api::Listen(socket, /*backlog=*/5));
219
220 QUICHE_EXPECT_OK(socket_api::Close(socket));
221 }
222
TEST(SocketTest,Accept)223 TEST(SocketTest, Accept) {
224 // Need a non-blocking socket to avoid waiting when no connection comes.
225 SocketFd socket =
226 CreateTestSocket(socket_api::SocketProtocol::kTcp, /*blocking=*/false);
227 QUICHE_ASSERT_OK(socket_api::Bind(
228 socket, QuicSocketAddress(quiche::TestLoopback(), /*port=*/0)));
229 QUICHE_ASSERT_OK(socket_api::Listen(socket, /*backlog=*/5));
230
231 // Nothing set up to connect, so expect kUnavailable.
232 absl::StatusOr<socket_api::AcceptResult> result = socket_api::Accept(socket);
233 EXPECT_THAT(result, StatusIs(absl::StatusCode::kUnavailable));
234
235 QUICHE_EXPECT_OK(socket_api::Close(socket));
236 }
237
TEST(SocketTest,Receive)238 TEST(SocketTest, Receive) {
239 // Non-blocking to avoid waiting when no data to receive.
240 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kUdp,
241 /*blocking=*/false);
242
243 // On Windows, recv() fails on a socket that is connectionless and not bound.
244 QUICHE_ASSERT_OK(socket_api::Bind(
245 socket, QuicSocketAddress(quiche::TestLoopback(), /*port=*/0)));
246
247 std::string buffer(100, 0);
248 absl::StatusOr<absl::Span<char>> result =
249 socket_api::Receive(socket, absl::MakeSpan(buffer));
250 EXPECT_THAT(result, StatusIs(absl::StatusCode::kUnavailable));
251
252 QUICHE_EXPECT_OK(socket_api::Close(socket));
253 }
254
TEST(SocketTest,Peek)255 TEST(SocketTest, Peek) {
256 // Non-blocking to avoid waiting when no data to receive.
257 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kUdp,
258 /*blocking=*/false);
259
260 // On Windows, recv() fails on a socket that is connectionless and not bound.
261 QUICHE_ASSERT_OK(socket_api::Bind(
262 socket, QuicSocketAddress(quiche::TestLoopback(), /*port=*/0)));
263
264 std::string buffer(100, 0);
265 absl::StatusOr<absl::Span<char>> result =
266 socket_api::Receive(socket, absl::MakeSpan(buffer), /*peek=*/true);
267 EXPECT_THAT(result, StatusIs(absl::StatusCode::kUnavailable));
268
269 QUICHE_EXPECT_OK(socket_api::Close(socket));
270 }
271
TEST(SocketTest,Send)272 TEST(SocketTest, Send) {
273 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kUdp);
274 // UDP, so "connecting" should succeed without any listening sockets.
275 QUICHE_ASSERT_OK(socket_api::Connect(
276 socket, QuicSocketAddress(quiche::TestLoopback(), /*port=*/0)));
277
278 char buffer[] = {12, 34, 56, 78};
279 // Expect at least some data to be sent successfully.
280 absl::StatusOr<absl::string_view> result =
281 socket_api::Send(socket, absl::string_view(buffer, sizeof(buffer)));
282 QUICHE_ASSERT_OK(result.status());
283 EXPECT_THAT(result.value(), SizeIs(Lt(4)));
284
285 QUICHE_EXPECT_OK(socket_api::Close(socket));
286 }
287
TEST(SocketTest,SendTo)288 TEST(SocketTest, SendTo) {
289 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kUdp);
290
291 // Send data to an arbitrarily-chosen ephemeral port.
292 char buffer[] = {12, 34, 56, 78};
293 absl::StatusOr<absl::string_view> result = socket_api::SendTo(
294 socket, QuicSocketAddress(quiche::TestLoopback(), /*port=*/57290),
295 absl::string_view(buffer, sizeof(buffer)));
296
297 // Expect at least some data to be sent successfully.
298 QUICHE_ASSERT_OK(result.status());
299 EXPECT_THAT(result.value(), SizeIs(Lt(4)));
300
301 QUICHE_EXPECT_OK(socket_api::Close(socket));
302 }
303
TEST(SocketTest,SendToWithConnection)304 TEST(SocketTest, SendToWithConnection) {
305 SocketFd socket = CreateTestSocket(socket_api::SocketProtocol::kUdp);
306 // UDP, so "connecting" should succeed without any listening sockets.
307 QUICHE_ASSERT_OK(socket_api::Connect(
308 socket, QuicSocketAddress(quiche::TestLoopback(), /*port=*/0)));
309
310 // Send data to an arbitrarily-chosen ephemeral port.
311 char buffer[] = {12, 34, 56, 78};
312 absl::StatusOr<absl::string_view> result = socket_api::SendTo(
313 socket, QuicSocketAddress(quiche::TestLoopback(), /*port=*/50495),
314 absl::string_view(buffer, sizeof(buffer)));
315 // Expect at least some data to be sent successfully.
316 QUICHE_ASSERT_OK(result.status());
317 EXPECT_THAT(result.value(), SizeIs(Lt(4)));
318
319 QUICHE_EXPECT_OK(socket_api::Close(socket));
320 }
321
TEST(SocketTest,SendToForRaw)322 TEST(SocketTest, SendToForRaw) {
323 SocketFd socket = CreateTestRawSocket(/*blocking=*/true);
324 if (socket == kInvalidSocketFd) {
325 GTEST_SKIP();
326 }
327
328 QuicIpAddress localhost_address = quiche::TestLoopback();
329 QUICHE_EXPECT_OK(socket_api::SetIpHeaderIncluded(
330 socket, localhost_address.address_family(),
331 /*ip_header_included=*/false));
332
333 // Arbitrarily-chosen ephemeral ports.
334 QuicSocketAddress client_address(localhost_address, /*port=*/53368);
335 QuicSocketAddress server_address(localhost_address, /*port=*/56362);
336 std::string packet = CreateUdpPacket(client_address, server_address, "foo");
337 absl::StatusOr<absl::string_view> result = socket_api::SendTo(
338 socket, QuicSocketAddress(localhost_address, /*port=*/56362), packet);
339
340 // Expect at least some data to be sent successfully.
341 QUICHE_ASSERT_OK(result.status());
342 EXPECT_THAT(result.value(), SizeIs(Lt(packet.size())));
343
344 QUICHE_EXPECT_OK(socket_api::Close(socket));
345 }
346
TEST(SocketTest,SendToForRawWithIpHeader)347 TEST(SocketTest, SendToForRawWithIpHeader) {
348 SocketFd socket = CreateTestRawSocket(/*blocking=*/true);
349 if (socket == kInvalidSocketFd) {
350 GTEST_SKIP();
351 }
352
353 QuicIpAddress localhost_address = quiche::TestLoopback();
354 QUICHE_EXPECT_OK(socket_api::SetIpHeaderIncluded(
355 socket, localhost_address.address_family(), /*ip_header_included=*/true));
356
357 // Arbitrarily-chosen ephemeral ports.
358 QuicSocketAddress client_address(localhost_address, /*port=*/53368);
359 QuicSocketAddress server_address(localhost_address, /*port=*/56362);
360 std::string packet =
361 CreateIpPacket(client_address.host(), server_address.host(),
362 CreateUdpPacket(client_address, server_address, "foo"));
363 absl::StatusOr<absl::string_view> result = socket_api::SendTo(
364 socket, QuicSocketAddress(localhost_address, /*port=*/56362), packet);
365
366 // Expect at least some data to be sent successfully.
367 QUICHE_ASSERT_OK(result.status());
368 EXPECT_THAT(result.value(), SizeIs(Lt(packet.size())));
369
370 QUICHE_EXPECT_OK(socket_api::Close(socket));
371 }
372
373 } // namespace
374 } // namespace quic::test
375