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_CONNECTING_CLIENT_SOCKET_H_ 6 #define QUICHE_QUIC_CORE_CONNECTING_CLIENT_SOCKET_H_ 7 8 #include <string> 9 10 #include "absl/status/status.h" 11 #include "absl/status/statusor.h" 12 #include "quiche/quic/core/quic_types.h" 13 #include "quiche/quic/platform/api/quic_socket_address.h" 14 #include "quiche/common/platform/api/quiche_export.h" 15 #include "quiche/common/platform/api/quiche_mem_slice.h" 16 17 namespace quic { 18 19 // A client socket that provides connection-based send/receive. In the case of 20 // protocols like UDP, may only be a pseudo-connection that doesn't actually 21 // affect the underlying network protocol. 22 // 23 // Must not destroy a connected/connecting socket. If connected or connecting, 24 // must call Disconnect() to disconnect or cancel the connection before 25 // destruction. 26 // 27 // Warning regarding blocking calls: Code in the QUICHE library typically 28 // handles IO on a single thread, so if making calls from that typical 29 // environment, it would be problematic to make a blocking call and block that 30 // single thread. 31 class QUICHE_EXPORT ConnectingClientSocket { 32 public: 33 class AsyncVisitor { 34 public: 35 virtual ~AsyncVisitor() = default; 36 37 virtual void ConnectComplete(absl::Status status) = 0; 38 39 // If the operation completed without error, `data` is set to the received 40 // data. 41 virtual void ReceiveComplete( 42 absl::StatusOr<quiche::QuicheMemSlice> data) = 0; 43 44 virtual void SendComplete(absl::Status status) = 0; 45 }; 46 47 virtual ~ConnectingClientSocket() = default; 48 49 // Establishes a connection synchronously. Should not be called if socket has 50 // already been successfully connected without first calling Disconnect(). 51 // 52 // After calling, the socket must not be destroyed until Disconnect() is 53 // called. 54 virtual absl::Status ConnectBlocking() = 0; 55 56 // Establishes a connection asynchronously. On completion, calls 57 // ConnectComplete() on the visitor, potentially before return from 58 // ConnectAsync(). Should not be called if socket has already been 59 // successfully connected without first calling Disconnect(). 60 // 61 // After calling, the socket must not be destroyed until Disconnect() is 62 // called. 63 virtual void ConnectAsync() = 0; 64 65 // Disconnects a connected socket or cancels an in-progress ConnectAsync(), 66 // invoking the `ConnectComplete(absl::CancelledError())` on the visitor. 67 // After success, it is possible to call ConnectBlocking() or ConnectAsync() 68 // again to establish a new connection. Cancels any pending read or write 69 // operations, calling visitor completion methods with 70 // `absl::CancelledError()`. 71 // 72 // Typically implemented via a call to ::close(), which for TCP can result in 73 // either FIN or RST, depending on socket/platform state and undefined 74 // platform behavior. 75 virtual void Disconnect() = 0; 76 77 // Gets the address assigned to a connected socket. 78 virtual absl::StatusOr<QuicSocketAddress> GetLocalAddress() = 0; 79 80 // Blocking read. Receives and returns a buffer of up to `max_size` bytes from 81 // socket. Returns status on error. 82 virtual absl::StatusOr<quiche::QuicheMemSlice> ReceiveBlocking( 83 QuicByteCount max_size) = 0; 84 85 // Asynchronous read. Receives up to `max_size` bytes from socket. If 86 // no data is synchronously available to be read, waits until some data is 87 // available or the socket is closed. On completion, calls ReceiveComplete() 88 // on the visitor, potentially before return from ReceiveAsync(). 89 // 90 // After calling, the socket must not be destroyed until ReceiveComplete() is 91 // called. 92 virtual void ReceiveAsync(QuicByteCount max_size) = 0; 93 94 // Blocking write. Sends all of `data` (potentially via multiple underlying 95 // socket sends). 96 virtual absl::Status SendBlocking(std::string data) = 0; 97 virtual absl::Status SendBlocking(quiche::QuicheMemSlice data) = 0; 98 99 // Asynchronous write. Sends all of `data` (potentially via multiple 100 // underlying socket sends). On completion, calls SendComplete() on the 101 // visitor, potentially before return from SendAsync(). 102 // 103 // After calling, the socket must not be destroyed until SendComplete() is 104 // called. 105 virtual void SendAsync(std::string data) = 0; 106 virtual void SendAsync(quiche::QuicheMemSlice data) = 0; 107 }; 108 109 } // namespace quic 110 111 #endif // QUICHE_QUIC_CORE_CONNECTING_CLIENT_SOCKET_H_ 112