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_EVENT_LOOP_CONNECTING_CLIENT_SOCKET_H_ 6 #define QUICHE_QUIC_CORE_IO_EVENT_LOOP_CONNECTING_CLIENT_SOCKET_H_ 7 8 #include <string> 9 10 #include "absl/status/status.h" 11 #include "absl/strings/string_view.h" 12 #include "absl/types/optional.h" 13 #include "absl/types/variant.h" 14 #include "quiche/quic/core/connecting_client_socket.h" 15 #include "quiche/quic/core/io/quic_event_loop.h" 16 #include "quiche/quic/core/io/socket.h" 17 #include "quiche/quic/core/quic_types.h" 18 #include "quiche/quic/platform/api/quic_socket_address.h" 19 #include "quiche/common/platform/api/quiche_export.h" 20 #include "quiche/common/quiche_buffer_allocator.h" 21 22 namespace quic { 23 24 // A connection-based client socket implemented using an underlying 25 // QuicEventLoop. 26 class QUICHE_EXPORT EventLoopConnectingClientSocket 27 : public ConnectingClientSocket, 28 public QuicSocketEventListener { 29 public: 30 // Will use platform default buffer size if `receive_buffer_size` or 31 // `send_buffer_size` is zero. `async_visitor` may be null if no async 32 // operations will be requested. `event_loop`, `buffer_allocator`, and 33 // `async_visitor` (if non-null) must outlive the created socket. 34 EventLoopConnectingClientSocket( 35 socket_api::SocketProtocol protocol, 36 const quic::QuicSocketAddress& peer_address, 37 QuicByteCount receive_buffer_size, QuicByteCount send_buffer_size, 38 QuicEventLoop* event_loop, 39 quiche::QuicheBufferAllocator* buffer_allocator, 40 AsyncVisitor* async_visitor); 41 42 ~EventLoopConnectingClientSocket() override; 43 44 // ConnectingClientSocket: 45 absl::Status ConnectBlocking() override; 46 void ConnectAsync() override; 47 void Disconnect() override; 48 absl::StatusOr<QuicSocketAddress> GetLocalAddress() override; 49 absl::StatusOr<quiche::QuicheMemSlice> ReceiveBlocking( 50 QuicByteCount max_size) override; 51 void ReceiveAsync(QuicByteCount max_size) override; 52 absl::Status SendBlocking(std::string data) override; 53 absl::Status SendBlocking(quiche::QuicheMemSlice data) override; 54 void SendAsync(std::string data) override; 55 void SendAsync(quiche::QuicheMemSlice data) override; 56 57 // QuicSocketEventListener: 58 void OnSocketEvent(QuicEventLoop* event_loop, SocketFd fd, 59 QuicSocketEventMask events) override; 60 61 private: 62 enum class ConnectStatus { 63 kNotConnected, 64 kConnecting, 65 kConnected, 66 }; 67 68 absl::Status Open(); 69 void Close(); 70 absl::Status DoInitialConnect(); 71 absl::Status GetConnectResult(); 72 void FinishOrRearmAsyncConnect(absl::Status status); 73 absl::StatusOr<quiche::QuicheMemSlice> ReceiveInternal(); 74 void FinishOrRearmAsyncReceive(absl::StatusOr<quiche::QuicheMemSlice> buffer); 75 // Returns `true` if a byte received, or `false` if successfully received 76 // empty data. 77 absl::StatusOr<bool> OneBytePeek(); 78 absl::Status SendBlockingInternal(); 79 absl::Status SendInternal(); 80 void FinishOrRearmAsyncSend(absl::Status status); 81 82 const socket_api::SocketProtocol protocol_; 83 const QuicSocketAddress peer_address_; 84 const QuicByteCount receive_buffer_size_; 85 const QuicByteCount send_buffer_size_; 86 QuicEventLoop* const event_loop_; // unowned 87 quiche::QuicheBufferAllocator* buffer_allocator_; // unowned 88 AsyncVisitor* const async_visitor_; // unowned, potentially null 89 90 SocketFd descriptor_ = kInvalidSocketFd; 91 ConnectStatus connect_status_ = ConnectStatus::kNotConnected; 92 93 // Only set while receive in progress or pending, otherwise nullopt. 94 absl::optional<QuicByteCount> receive_max_size_; 95 96 // Only contains data while send in progress or pending, otherwise monostate. 97 absl::variant<absl::monostate, std::string, quiche::QuicheMemSlice> 98 send_data_; 99 // Points to the unsent portion of `send_data_` while send in progress or 100 // pending, otherwise empty. 101 absl::string_view send_remaining_; 102 }; 103 104 } // namespace quic 105 106 #endif // QUICHE_QUIC_CORE_IO_EVENT_LOOP_CONNECTING_CLIENT_SOCKET_H_ 107