• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Chromium Authors
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 NET_QUIC_DEDICATED_WEB_TRANSPORT_HTTP3_CLIENT_H_
6 #define NET_QUIC_DEDICATED_WEB_TRANSPORT_HTTP3_CLIENT_H_
7 
8 #include <optional>
9 #include <string_view>
10 
11 #include "base/memory/raw_ptr.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/task/sequenced_task_runner.h"
14 #include "net/base/network_anonymization_key.h"
15 #include "net/dns/host_resolver.h"
16 #include "net/log/net_log_with_source.h"
17 #include "net/proxy_resolution/proxy_info.h"
18 #include "net/quic/quic_chromium_packet_reader.h"
19 #include "net/quic/quic_chromium_packet_writer.h"
20 #include "net/quic/quic_context.h"
21 #include "net/quic/quic_event_logger.h"
22 #include "net/quic/web_transport_client.h"
23 #include "net/quic/web_transport_error.h"
24 #include "net/socket/client_socket_factory.h"
25 #include "net/third_party/quiche/src/quiche/common/http/http_header_block.h"
26 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_client_config.h"
27 #include "net/third_party/quiche/src/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h"
28 #include "net/third_party/quiche/src/quiche/quic/core/deterministic_connection_id_generator.h"
29 #include "net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_client_session.h"
30 #include "net/third_party/quiche/src/quiche/quic/core/quic_config.h"
31 #include "net/third_party/quiche/src/quiche/quic/core/quic_connection_id.h"
32 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
33 #include "net/third_party/quiche/src/quiche/quic/core/web_transport_interface.h"
34 #include "url/gurl.h"
35 #include "url/origin.h"
36 
37 namespace net {
38 
39 class ProxyResolutionRequest;
40 class QuicChromiumAlarmFactory;
41 class URLRequestContext;
42 
43 // Creates a dedicated HTTP/3 connection for a WebTransport session.
44 class NET_EXPORT DedicatedWebTransportHttp3Client
45     : public WebTransportClient,
46       public quic::WebTransportVisitor,
47       public QuicChromiumPacketReader::Visitor,
48       public QuicChromiumPacketWriter::Delegate {
49  public:
50   // |visitor| and |context| must outlive this object.
51   DedicatedWebTransportHttp3Client(
52       const GURL& url,
53       const url::Origin& origin,
54       WebTransportClientVisitor* visitor,
55       const NetworkAnonymizationKey& anonymization_key,
56       URLRequestContext* context,
57       const WebTransportParameters& parameters);
58   ~DedicatedWebTransportHttp3Client() override;
59 
state()60   WebTransportState state() const { return state_; }
61 
62   // Connect() is an asynchronous operation.  Once the operation is finished,
63   // OnConnected() or OnConnectionFailed() is called on the Visitor.
64   void Connect() override;
65   void Close(const std::optional<WebTransportCloseInfo>& close_info) override;
66 
67   quic::WebTransportSession* session() override;
68 
69   void OnSettingsReceived();
70   void OnHeadersComplete(const quiche::HttpHeaderBlock& headers);
71   void OnConnectStreamWriteSideInDataRecvdState();
72   void OnConnectStreamAborted();
73   void OnConnectStreamDeleted();
74   void OnCloseTimeout();
75   void OnDatagramProcessed(std::optional<quic::MessageStatus> status);
76 
77   // QuicTransportClientSession::ClientVisitor methods.
78   void OnSessionReady() override;
79   void OnSessionClosed(quic::WebTransportSessionError error_code,
80                        const std::string& error_message) override;
81   void OnIncomingBidirectionalStreamAvailable() override;
82   void OnIncomingUnidirectionalStreamAvailable() override;
83   void OnDatagramReceived(std::string_view datagram) override;
84   void OnCanCreateNewOutgoingBidirectionalStream() override;
85   void OnCanCreateNewOutgoingUnidirectionalStream() override;
86 
87   // QuicChromiumPacketReader::Visitor methods.
88   bool OnReadError(int result, const DatagramClientSocket* socket) override;
89   bool OnPacket(const quic::QuicReceivedPacket& packet,
90                 const quic::QuicSocketAddress& local_address,
91                 const quic::QuicSocketAddress& peer_address) override;
92 
93   // QuicChromiumPacketWriter::Delegate methods.
94   int HandleWriteError(int error_code,
95                        scoped_refptr<QuicChromiumPacketWriter::ReusableIOBuffer>
96                            last_packet) override;
97   void OnWriteError(int error_code) override;
98   void OnWriteUnblocked() override;
99 
100   void OnConnectionClosed(quic::QuicErrorCode error,
101                           const std::string& error_details,
102                           quic::ConnectionCloseSource source);
103 
104  private:
105   // State of the connection establishment process.
106   enum ConnectState {
107     CONNECT_STATE_NONE,
108     CONNECT_STATE_INIT,
109     CONNECT_STATE_CHECK_PROXY,
110     CONNECT_STATE_CHECK_PROXY_COMPLETE,
111     CONNECT_STATE_RESOLVE_HOST,
112     CONNECT_STATE_RESOLVE_HOST_COMPLETE,
113     CONNECT_STATE_CONNECT,
114     CONNECT_STATE_CONNECT_CONFIGURE,
115     CONNECT_STATE_CONNECT_COMPLETE,
116     CONNECT_STATE_SEND_REQUEST,
117     CONNECT_STATE_CONFIRM_CONNECTION,
118 
119     CONNECT_STATE_NUM_STATES,
120   };
121 
122   // DoLoop processing the Connect() call.
123   void DoLoop(int rv);
124   // Verifies the basic preconditions for setting up the connection.
125   int DoInit();
126   // Verifies that there is no mandatory proxy configured for the specified URL.
127   int DoCheckProxy();
128   int DoCheckProxyComplete(int rv);
129   // Resolves the hostname in the URL.
130   int DoResolveHost();
131   int DoResolveHostComplete(int rv);
132   // Establishes the QUIC connection.
133   int DoConnect();
134   int DoConnectConfigure(int rv);
135   int DoConnectComplete();
136   void CreateConnection();
137   // Sends the CONNECT request to establish a WebTransport session.
138   int DoSendRequest();
139   // Verifies that the connection has succeeded.
140   int DoConfirmConnection();
141 
142   void TransitionToState(WebTransportState next_state);
143 
144   void SetErrorIfNecessary(int error);
145   void SetErrorIfNecessary(int error,
146                            quic::QuicErrorCode quic_error,
147                            std::string_view details);
148 
149   const GURL url_;
150   const url::Origin origin_;
151   const NetworkAnonymizationKey anonymization_key_;
152   const raw_ptr<URLRequestContext> context_;          // Unowned.
153   const raw_ptr<WebTransportClientVisitor> visitor_;  // Unowned.
154 
155   const raw_ptr<QuicContext> quic_context_;                   // Unowned.
156   NetLogWithSource net_log_;
157   raw_ptr<base::SequencedTaskRunner> task_runner_;  // Unowned.
158 
159   quic::ParsedQuicVersionVector supported_versions_;
160   // |original_supported_versions_| starts off empty. If a version negotiation
161   // packet is received, versions not supported by the server are removed from
162   // |supported_versions_| but the original list is saved in
163   // |original_supported_versions_|. This prevents version downgrade attacks.
164   quic::ParsedQuicVersionVector original_supported_versions_;
165   // TODO(vasilvv): move some of those into QuicContext.
166   std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
167   quic::QuicCryptoClientConfig crypto_config_;
168 
169   WebTransportState state_ = WebTransportState::NEW;
170   ConnectState next_connect_state_ = CONNECT_STATE_NONE;
171   std::optional<WebTransportError> error_;
172   bool retried_with_new_version_ = false;
173   bool session_ready_ = false;
174   bool safe_to_report_error_details_ = false;
175   std::unique_ptr<HttpResponseInfo> http_response_info_;
176 
177   ProxyInfo proxy_info_;
178   std::unique_ptr<ProxyResolutionRequest> proxy_resolution_request_;
179   std::unique_ptr<HostResolver::ResolveHostRequest> resolve_host_request_;
180 
181   std::unique_ptr<DatagramClientSocket> socket_;
182   // This must be destroyed after `session_`, as it owns the underlying socket
183   // and `session_` owns the packet writer, which has a raw pointer to the
184   // socket.
185   std::unique_ptr<QuicChromiumPacketReader> packet_reader_;
186   std::unique_ptr<quic::QuicSpdyClientSession> session_;
187   raw_ptr<quic::QuicConnection> connection_;  // owned by |session_|
188   raw_ptr<quic::WebTransportSession> web_transport_session_ = nullptr;
189   std::unique_ptr<QuicEventLogger> event_logger_;
190   quic::DeterministicConnectionIdGenerator connection_id_generator_{
191       quic::kQuicDefaultConnectionIdLength};
192 
193   std::optional<WebTransportCloseInfo> close_info_;
194 
195   base::OneShotTimer close_timeout_timer_;
196   base::WeakPtrFactory<DedicatedWebTransportHttp3Client> weak_factory_{this};
197 };
198 
199 }  // namespace net
200 
201 #endif  // NET_QUIC_DEDICATED_WEB_TRANSPORT_HTTP3_CLIENT_H_
202