xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/io/socket.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 #ifndef QUICHE_QUIC_CORE_IO_SOCKET_H_
6 #define QUICHE_QUIC_CORE_IO_SOCKET_H_
7 
8 #include "absl/status/status.h"
9 #include "absl/status/statusor.h"
10 #include "absl/strings/string_view.h"
11 #include "absl/types/span.h"
12 #include "quiche/quic/core/quic_types.h"
13 #include "quiche/quic/platform/api/quic_ip_address_family.h"
14 #include "quiche/quic/platform/api/quic_socket_address.h"
15 
16 #if defined(_WIN32)
17 #include <winsock2.h>
18 #else
19 #include <sys/socket.h>
20 #endif  // defined(_WIN32)
21 
22 namespace quic {
23 
24 #if defined(_WIN32)
25 using SocketFd = SOCKET;
26 inline constexpr SocketFd kInvalidSocketFd = INVALID_SOCKET;
27 inline constexpr int kSocketErrorMsgSize = WSAEMSGSIZE;
28 #else
29 using SocketFd = int;
30 inline constexpr SocketFd kInvalidSocketFd = -1;
31 inline constexpr int kSocketErrorMsgSize = EMSGSIZE;
32 #endif
33 
34 // Low-level platform-agnostic socket operations. Closely follows the behavior
35 // of basic POSIX socket APIs, diverging mostly only to convert to/from cleaner
36 // and platform-agnostic types.
37 namespace socket_api {
38 enum class SocketProtocol {
39   kUdp,
40   kTcp,
41   kRawIp,
42 };
43 
GetProtocolName(SocketProtocol protocol)44 inline absl::string_view GetProtocolName(SocketProtocol protocol) {
45   switch (protocol) {
46     case SocketProtocol::kUdp:
47       return "UDP";
48     case SocketProtocol::kTcp:
49       return "TCP";
50     case SocketProtocol::kRawIp:
51       return "RAW_IP";
52   }
53 
54   return "unknown";
55 }
56 
57 struct AcceptResult {
58   // Socket for interacting with the accepted connection.
59   SocketFd fd;
60 
61   // Address of the connected peer.
62   QuicSocketAddress peer_address;
63 };
64 
65 // Creates a socket with blocking or non-blocking behavior.
66 absl::StatusOr<SocketFd> CreateSocket(IpAddressFamily address_family,
67                                       SocketProtocol protocol,
68                                       bool blocking = false);
69 
70 // Sets socket `fd` to blocking (if `blocking` true) or non-blocking (if
71 // `blocking` false). Must be a change from previous state.
72 absl::Status SetSocketBlocking(SocketFd fd, bool blocking);
73 
74 // Sets buffer sizes for socket `fd` to `size` bytes.
75 absl::Status SetReceiveBufferSize(SocketFd fd, QuicByteCount size);
76 absl::Status SetSendBufferSize(SocketFd fd, QuicByteCount size);
77 
78 // Only allowed for raw IP sockets. If set, sent data buffers include the IP
79 // header. If not set, sent data buffers only contain the IP packet payload, and
80 // the header will be generated.
81 absl::Status SetIpHeaderIncluded(SocketFd fd, IpAddressFamily address_family,
82                                  bool ip_header_included);
83 
84 // Connects socket `fd` to `peer_address`.  Returns a status with
85 // `absl::StatusCode::kUnavailable` iff the socket is non-blocking and the
86 // connection could not be immediately completed.  The socket will then complete
87 // connecting asynchronously, and on becoming writable, the result can be
88 // checked using GetSocketError().
89 absl::Status Connect(SocketFd fd, const QuicSocketAddress& peer_address);
90 
91 // Gets and clears socket error information for socket `fd`. Note that returned
92 // error could be either the found socket error, or unusually, an error from the
93 // attempt to retrieve error information. Typically used to determine connection
94 // result after asynchronous completion of a Connect() call.
95 absl::Status GetSocketError(SocketFd fd);
96 
97 // Assign `address` to socket `fd`.
98 absl::Status Bind(SocketFd fd, const QuicSocketAddress& address);
99 
100 // Gets the address assigned to socket `fd`.
101 absl::StatusOr<QuicSocketAddress> GetSocketAddress(SocketFd fd);
102 
103 // Marks socket `fd` as a passive socket listening for connection requests.
104 // `backlog` is the maximum number of queued connection requests. Typically
105 // expected to return a status with `absl::StatusCode::InvalidArgumentError`
106 // if `fd` is not a TCP socket.
107 absl::Status Listen(SocketFd fd, int backlog);
108 
109 // Accepts an incoming connection to the listening socket `fd`.  The returned
110 // connection socket will be set as non-blocking iff `blocking` is false.
111 // Typically expected to return a status with
112 // `absl::StatusCode::InvalidArgumentError` if `fd` is not a TCP socket or not
113 // listening for connections.  Returns a status with
114 // `absl::StatusCode::kUnavailable` iff the socket is non-blocking and no
115 // incoming connection could be immediately accepted.
116 absl::StatusOr<AcceptResult> Accept(SocketFd fd, bool blocking = false);
117 
118 // Receives data from socket `fd`. Will fill `buffer.data()` with up to
119 // `buffer.size()` bytes. On success, returns a span pointing to the buffer
120 // but resized to the actual number of bytes received. Returns a status with
121 // `absl::StatusCode::kUnavailable` iff the socket is non-blocking and the
122 // receive operation could not be immediately completed.  If `peek` is true,
123 // received data is not removed from the underlying socket data queue.
124 absl::StatusOr<absl::Span<char>> Receive(SocketFd fd, absl::Span<char> buffer,
125                                          bool peek = false);
126 
127 // Sends some or all of the data in `buffer` to socket `fd`. On success,
128 // returns a string_view pointing to the unsent remainder of the buffer (or an
129 // empty string_view if all of `buffer` was successfully sent). Returns a status
130 // with `absl::StatusCode::kUnavailable` iff the socket is non-blocking and the
131 // send operation could not be immediately completed.
132 absl::StatusOr<absl::string_view> Send(SocketFd fd, absl::string_view buffer);
133 
134 // Same as Send() except a specific address (`peer_address`) is specified for
135 // where to send the data to. Typically used for non-connected sockets.
136 absl::StatusOr<absl::string_view> SendTo(SocketFd fd,
137                                          const QuicSocketAddress& peer_address,
138                                          absl::string_view buffer);
139 
140 // Closes socket `fd`.
141 absl::Status Close(SocketFd fd);
142 }  // namespace socket_api
143 
144 }  // namespace quic
145 
146 #endif  // QUICHE_QUIC_CORE_IO_SOCKET_H_
147