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