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