summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quiche/quic/core/io/socket.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/third_party/quiche/src/quiche/quic/core/io/socket.h')
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/io/socket.h172
1 files changed, 172 insertions, 0 deletions
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/io/socket.h b/chromium/net/third_party/quiche/src/quiche/quic/core/io/socket.h
new file mode 100644
index 00000000000..fcc6418ac49
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/io/socket.h
@@ -0,0 +1,172 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_IO_SOCKET_H_
+#define QUICHE_QUIC_CORE_IO_SOCKET_H_
+
+#include <functional>
+#include <string>
+
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/platform/api/quic_ip_address_family.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+#if defined(_WIN32)
+#include <winsock2.h>
+#endif // defined(_WIN32)
+
+namespace quic {
+
+#if defined(_WIN32)
+using SocketFd = SOCKET;
+inline constexpr SocketFd kInvalidSocketFd = INVALID_SOCKET;
+#else
+using SocketFd = int;
+inline constexpr SocketFd kInvalidSocketFd = -1;
+#endif
+
+// A read/write socket.
+//
+// Warning regarding blocking calls: Code in the QUICHE library typically
+// handles IO on a single thread, so if making calls from that typical
+// environment, it would be problematic to make a blocking call and block that
+// single thread.
+class QUICHE_EXPORT_PRIVATE Socket {
+ public:
+ class AsyncVisitor {
+ public:
+ virtual ~AsyncVisitor() = default;
+
+ // If the operation completed without error, `data` is set to the received
+ // data.
+ virtual void ReceiveComplete(
+ absl::StatusOr<quiche::QuicheMemSlice> data) = 0;
+
+ virtual void SendComplete(absl::Status status) = 0;
+ };
+
+ virtual ~Socket() = default;
+
+ // Blocking read. Receives and returns a buffer of up to `max_size` bytes from
+ // socket. Returns status on error.
+ virtual absl::StatusOr<quiche::QuicheMemSlice> ReceiveBlocking(
+ QuicByteCount max_size) = 0;
+
+ // Asynchronous read. Receives up to `max_size` bytes from socket. If
+ // no data is synchronously available to be read, waits until some data is
+ // available or the socket is closed. On completion, calls ReceiveComplete()
+ // on the visitor, potentially before return from ReceiveAsync().
+ //
+ // After calling, the socket must not be destroyed until ReceiveComplete() is
+ // called.
+ virtual void ReceiveAsync(QuicByteCount max_size) = 0;
+
+ // Blocking write. Sends all of `data` (potentially via multiple underlying
+ // socket sends).
+ virtual absl::Status SendBlocking(std::string data) = 0;
+ virtual absl::Status SendBlocking(quiche::QuicheMemSlice data) = 0;
+
+ // Asynchronous write. Sends all of `data` (potentially via multiple
+ // underlying socket sends). On completion, calls SendComplete() on the
+ // visitor, potentially before return from SendAsync().
+ //
+ // After calling, the socket must not be destroyed until SendComplete() is
+ // called.
+ virtual void SendAsync(std::string data) = 0;
+ virtual void SendAsync(quiche::QuicheMemSlice data) = 0;
+};
+
+// Low-level platform-agnostic socket operations. Closely follows the behavior
+// of basic POSIX socket APIs, diverging mostly only to convert to/from cleaner
+// and platform-agnostic types.
+namespace socket_api {
+enum class SocketProtocol {
+ kUdp,
+ kTcp,
+};
+
+struct QUICHE_EXPORT_PRIVATE AcceptResult {
+ // Socket for interacting with the accepted connection.
+ SocketFd fd;
+
+ // Address of the connected peer.
+ QuicSocketAddress peer_address;
+};
+
+// Creates a socket with blocking or non-blocking behavior.
+absl::StatusOr<SocketFd> CreateSocket(IpAddressFamily address_family,
+ SocketProtocol protocol,
+ bool blocking = false);
+
+// Sets socket `fd` to blocking (if `blocking` true) or non-blocking (if
+// `blocking` false). Must be a change from previous state.
+absl::Status SetSocketBlocking(SocketFd fd, bool blocking);
+
+// Sets buffer sizes for socket `fd` to `size` bytes.
+absl::Status SetReceiveBufferSize(SocketFd fd, QuicByteCount size);
+absl::Status SetSendBufferSize(SocketFd fd, QuicByteCount size);
+
+// Connects socket `fd` to `peer_address`. Returns a status with
+// `absl::StatusCode::kUnavailable` iff the socket is non-blocking and the
+// connection could not be immediately completed. The socket will then complete
+// connecting asynchronously, and on becoming writable, the result can be
+// checked using GetSocketError().
+absl::Status Connect(SocketFd fd, const QuicSocketAddress& peer_address);
+
+// Gets and clears socket error information for socket `fd`. Note that returned
+// error could be either the found socket error, or unusually, an error from the
+// attempt to retrieve error information. Typically used to determine connection
+// result after asynchronous completion of a Connect() call.
+absl::Status GetSocketError(SocketFd fd);
+
+// Assign `address` to socket `fd`.
+absl::Status Bind(SocketFd fd, const QuicSocketAddress& address);
+
+// Gets the address assigned to socket `fd`.
+absl::StatusOr<QuicSocketAddress> GetSocketAddress(SocketFd fd);
+
+// Marks socket `fd` as a passive socket listening for connection requests.
+// `backlog` is the maximum number of queued connection requests. Typically
+// expected to return a status with `absl::StatusCode::InvalidArgumentError`
+// if `fd` is not a TCP socket.
+absl::Status Listen(SocketFd fd, int backlog);
+
+// Accepts an incoming connection to the listening socket `fd`. The returned
+// connection socket will be set as non-blocking iff `blocking` is false.
+// Typically expected to return a status with
+// `absl::StatusCode::InvalidArgumentError` if `fd` is not a TCP socket or not
+// listening for connections. Returns a status with
+// `absl::StatusCode::kUnavailable` iff the socket is non-blocking and no
+// incoming connection could be immediately accepted.
+absl::StatusOr<AcceptResult> Accept(SocketFd fd, bool blocking = false);
+
+// Receives data from socket `fd`. Will fill `buffer.data()` with up to
+// `buffer.size()` bytes. On success, returns a span pointing to the buffer
+// but resized to the actual number of bytes received. Returns a status with
+// `absl::StatusCode::kUnavailable` iff the socket is non-blocking and the
+// receive operation could not be immediately completed. If `peek` is true,
+// received data is not removed from the underlying socket data queue.
+absl::StatusOr<absl::Span<char>> Receive(SocketFd fd, absl::Span<char> buffer,
+ bool peek = false);
+
+// Sends some or all of the data in `buffer` to socket `fd`. On success,
+// returns a string_view pointing to the unsent remainder of the buffer (or an
+// empty string_view if all of `buffer` was successfully sent). Returns a status
+// with `absl::StatusCode::kUnavailable` iff the socket is non-blocking and the
+// send operation could not be immediately completed.
+absl::StatusOr<absl::string_view> Send(SocketFd fd, absl::string_view buffer);
+
+// Closes socket `fd`.
+absl::Status Close(SocketFd fd);
+} // namespace socket_api
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_CORE_IO_SOCKET_H_