xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/tools/connect_tunnel.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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_TOOLS_CONNECT_TUNNEL_H_
6 #define QUICHE_QUIC_TOOLS_CONNECT_TUNNEL_H_
7 
8 #include <cstdint>
9 #include <memory>
10 #include <string>
11 #include <utility>
12 
13 #include "absl/container/flat_hash_set.h"
14 #include "absl/status/status.h"
15 #include "absl/status/statusor.h"
16 #include "absl/strings/string_view.h"
17 #include "quiche/quic/core/connecting_client_socket.h"
18 #include "quiche/quic/core/quic_error_codes.h"
19 #include "quiche/quic/core/quic_server_id.h"
20 #include "quiche/quic/core/socket_factory.h"
21 #include "quiche/quic/tools/quic_simple_server_backend.h"
22 #include "quiche/common/platform/api/quiche_mem_slice.h"
23 #include "quiche/spdy/core/http2_header_block.h"
24 
25 namespace quic {
26 
27 // Manages a single connection tunneled over a CONNECT proxy.
28 class ConnectTunnel : public ConnectingClientSocket::AsyncVisitor {
29  public:
30   // `client_stream_request_handler` and `socket_factory` must both outlive the
31   // created ConnectTunnel.
32   ConnectTunnel(
33       QuicSimpleServerBackend::RequestHandler* client_stream_request_handler,
34       SocketFactory* socket_factory,
35       absl::flat_hash_set<QuicServerId> acceptable_destinations);
36   ~ConnectTunnel();
37   ConnectTunnel(const ConnectTunnel&) = delete;
38   ConnectTunnel& operator=(const ConnectTunnel&) = delete;
39 
40   // Attempts to open TCP connection to destination server and then sends
41   // appropriate success/error response to the request stream. `request_headers`
42   // must represent headers from a CONNECT request, that is ":method"="CONNECT"
43   // and no ":protocol".
44   void OpenTunnel(const spdy::Http2HeaderBlock& request_headers);
45 
46   // Returns true iff the connection to the destination server is currently open
47   bool IsConnectedToDestination() const;
48 
49   void SendDataToDestination(absl::string_view data);
50 
51   // Called when the client stream has been closed.  Connection to destination
52   // server is closed if connected.  The RequestHandler will no longer be
53   // interacted with after completion.
54   void OnClientStreamClose();
55 
56   // ConnectingClientSocket::AsyncVisitor:
57   void ConnectComplete(absl::Status status) override;
58   void ReceiveComplete(absl::StatusOr<quiche::QuicheMemSlice> data) override;
59   void SendComplete(absl::Status status) override;
60 
61  private:
62   void BeginAsyncReadFromDestination();
63   void OnDataReceivedFromDestination(bool success);
64 
65   // For normal (FIN) closure. Errors (RST) should result in directly calling
66   // TerminateClientStream().
67   void OnDestinationConnectionClosed();
68 
69   void SendConnectResponse();
70   void TerminateClientStream(
71       absl::string_view error_description,
72       QuicResetStreamError error_code =
73           QuicResetStreamError::FromIetf(QuicHttp3ErrorCode::CONNECT_ERROR));
74 
75   const absl::flat_hash_set<QuicServerId> acceptable_destinations_;
76   SocketFactory* const socket_factory_;
77 
78   // Null when client stream closed.
79   QuicSimpleServerBackend::RequestHandler* client_stream_request_handler_;
80 
81   // Null when destination connection disconnected.
82   std::unique_ptr<ConnectingClientSocket> destination_socket_;
83 
84   bool receive_started_ = false;
85 };
86 
87 }  // namespace quic
88 
89 #endif  // QUICHE_QUIC_TOOLS_CONNECT_TUNNEL_H_
90