• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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