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