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