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