#include "net/quic/quic_session_pool.h"
#include <memory>
#include <set>
#include <string_view>
#include <tuple>
#include <utility>
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/not_fatal_until.h"
#include "base/numerics/safe_conversions.h"
#include "base/ranges/algorithm.h"
#include "base/strings/escape.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/values.h"
#include "crypto/openssl_util.h"
#include "net/base/address_list.h"
#include "net/base/connection_endpoint_metadata.h"
#include "net/base/features.h"
#include "net/base/http_user_agent_settings.h"
#include "net/base/ip_address.h"
#include "net/base/net_errors.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/network_handle.h"
#include "net/base/proxy_delegate.h"
#include "net/base/session_usage.h"
#include "net/base/trace_constants.h"
#include "net/base/tracing.h"
#include "net/base/url_util.h"
#include "net/cert/cert_verifier.h"
#include "net/dns/host_resolver.h"
#include "net/dns/public/secure_dns_policy.h"
#include "net/log/net_log.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source_type.h"
#include "net/quic/address_utils.h"
#include "net/quic/crypto/proof_verifier_chromium.h"
#include "net/quic/properties_based_quic_server_info.h"
#include "net/quic/quic_chromium_alarm_factory.h"
#include "net/quic/quic_chromium_client_session.h"
#include "net/quic/quic_chromium_connection_helper.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_crypto_client_stream_factory.h"
#include "net/quic/quic_server_info.h"
#include "net/quic/quic_session_key.h"
#include "net/quic/quic_session_pool_direct_job.h"
#include "net/quic/quic_session_pool_job.h"
#include "net/quic/quic_session_pool_proxy_job.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/next_proto.h"
#include "net/socket/socket_performance_watcher.h"
#include "net/socket/socket_performance_watcher_factory.h"
#include "net/socket/udp_client_socket.h"
#include "net/third_party/quiche/src/quiche/quic/core/crypto/null_decrypter.h"
#include "net/third_party/quiche/src/quiche/quic/core/crypto/proof_verifier.h"
#include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_random.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_clock.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_connection.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quiche/quic/platform/api/quic_flags.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "third_party/boringssl/src/include/openssl/aead.h"
#include "url/gurl.h"
#include "url/scheme_host_port.h"
#include "url/url_constants.h"
namespace net {
namespace {
enum InitialRttEstimateSource { … };
enum FindMatchingIpSessionResult { … };
std::string QuicPlatformNotificationToString(
QuicPlatformNotification notification) { … }
const char* AllActiveSessionsGoingAwayReasonToString(
AllActiveSessionsGoingAwayReason reason) { … }
void HistogramCreateSessionFailure(enum CreateSessionFailure error) { … }
void LogFindMatchingIpSessionResult(const NetLogWithSource& net_log,
FindMatchingIpSessionResult result,
QuicChromiumClientSession* session,
const url::SchemeHostPort& destination) { … }
void SetInitialRttEstimate(base::TimeDelta estimate,
enum InitialRttEstimateSource source,
quic::QuicConfig* config) { … }
class ServerIdOriginFilter
: public quic::QuicCryptoClientConfig::ServerIdFilter { … };
std::set<std::string> HostsFromOrigins(std::set<HostPortPair> origins) { … }
void LogUsingExistingSession(const NetLogWithSource& request_net_log,
QuicChromiumClientSession* session,
const url::SchemeHostPort& destination) { … }
}
QuicSessionRequest::QuicSessionRequest(QuicSessionPool* pool) : … { … }
QuicSessionRequest::~QuicSessionRequest() { … }
int QuicSessionRequest::Request(
url::SchemeHostPort destination,
quic::ParsedQuicVersion quic_version,
const ProxyChain& proxy_chain,
const std::optional<NetworkTrafficAnnotationTag> proxy_annotation_tag,
const HttpUserAgentSettings* http_user_agent_settings,
SessionUsage session_usage,
PrivacyMode privacy_mode,
RequestPriority priority,
const SocketTag& socket_tag,
const NetworkAnonymizationKey& network_anonymization_key,
SecureDnsPolicy secure_dns_policy,
bool require_dns_https_alpn,
int cert_verify_flags,
const GURL& url,
const NetLogWithSource& net_log,
NetErrorDetails* net_error_details,
CompletionOnceCallback failed_on_default_network_callback,
CompletionOnceCallback callback) { … }
bool QuicSessionRequest::WaitForHostResolution(
CompletionOnceCallback callback) { … }
void QuicSessionRequest::ExpectOnHostResolution() { … }
void QuicSessionRequest::OnHostResolutionComplete(
int rv,
base::TimeTicks dns_resolution_start_time,
base::TimeTicks dns_resolution_end_time) { … }
bool QuicSessionRequest::WaitForQuicSessionCreation(
CompletionOnceCallback callback) { … }
void QuicSessionRequest::ExpectQuicSessionCreation() { … }
void QuicSessionRequest::OnQuicSessionCreationComplete(int rv) { … }
void QuicSessionRequest::OnRequestComplete(int rv) { … }
void QuicSessionRequest::OnConnectionFailedOnDefaultNetwork() { … }
base::TimeDelta QuicSessionRequest::GetTimeDelayForWaitingJob() const { … }
void QuicSessionRequest::SetPriority(RequestPriority priority) { … }
std::unique_ptr<QuicChromiumClientSession::Handle>
QuicSessionRequest::ReleaseSessionHandle() { … }
void QuicSessionRequest::SetSession(
std::unique_ptr<QuicChromiumClientSession::Handle> session) { … }
QuicEndpoint::QuicEndpoint(quic::ParsedQuicVersion quic_version,
IPEndPoint ip_endpoint,
ConnectionEndpointMetadata metadata)
: … { … }
QuicEndpoint::~QuicEndpoint() = default;
base::Value::Dict QuicEndpoint::ToValue() const { … }
QuicSessionPool::QuicCryptoClientConfigOwner::QuicCryptoClientConfigOwner(
std::unique_ptr<quic::ProofVerifier> proof_verifier,
std::unique_ptr<quic::QuicClientSessionCache> session_cache,
QuicSessionPool* quic_session_pool)
: … { … }
QuicSessionPool::QuicCryptoClientConfigOwner::~QuicCryptoClientConfigOwner() { … }
void QuicSessionPool::QuicCryptoClientConfigOwner::OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { … }
QuicSessionPool::CryptoClientConfigHandle::CryptoClientConfigHandle(
const QuicCryptoClientConfigMap::iterator& map_iterator)
: … { … }
QuicSessionPool::CryptoClientConfigHandle::~CryptoClientConfigHandle() { … }
quic::QuicCryptoClientConfig*
QuicSessionPool::CryptoClientConfigHandle::GetConfig() const { … }
QuicSessionPool::QuicSessionPool(
NetLog* net_log,
HostResolver* host_resolver,
SSLConfigService* ssl_config_service,
ClientSocketFactory* client_socket_factory,
HttpServerProperties* http_server_properties,
CertVerifier* cert_verifier,
TransportSecurityState* transport_security_state,
ProxyDelegate* proxy_delegate,
SCTAuditingDelegate* sct_auditing_delegate,
SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory,
QuicContext* quic_context)
: … { … }
QuicSessionPool::~QuicSessionPool() { … }
bool QuicSessionPool::CanUseExistingSession(
const QuicSessionKey& session_key,
const url::SchemeHostPort& destination) const { … }
QuicChromiumClientSession* QuicSessionPool::FindExistingSession(
const QuicSessionKey& session_key,
const url::SchemeHostPort& destination) const { … }
bool QuicSessionPool::HasMatchingIpSessionForServiceEndpoint(
const QuicSessionAliasKey& session_alias_key,
const ServiceEndpoint& service_endpoint,
const std::set<std::string>& dns_aliases,
bool use_dns_aliases) { … }
int QuicSessionPool::RequestSession(
const QuicSessionKey& session_key,
url::SchemeHostPort destination,
quic::ParsedQuicVersion quic_version,
const std::optional<NetworkTrafficAnnotationTag> proxy_annotation_tag,
const HttpUserAgentSettings* http_user_agent_settings,
RequestPriority priority,
bool use_dns_aliases,
int cert_verify_flags,
const GURL& url,
const NetLogWithSource& net_log,
QuicSessionRequest* request) { … }
std::unique_ptr<QuicSessionAttempt> QuicSessionPool::CreateSessionAttempt(
QuicSessionAttempt::Delegate* delegate,
const QuicSessionKey& session_key,
QuicEndpoint quic_endpoint,
int cert_verify_flags,
base::TimeTicks dns_resolution_start_time,
base::TimeTicks dns_resolution_end_time,
bool use_dns_aliases,
std::set<std::string> dns_aliases) { … }
void QuicSessionPool::OnSessionGoingAway(QuicChromiumClientSession* session) { … }
void QuicSessionPool::OnSessionClosed(QuicChromiumClientSession* session) { … }
void QuicSessionPool::OnBlackholeAfterHandshakeConfirmed(
QuicChromiumClientSession* session) { … }
void QuicSessionPool::CancelRequest(QuicSessionRequest* request) { … }
void QuicSessionPool::SetRequestPriority(QuicSessionRequest* request,
RequestPriority priority) { … }
void QuicSessionPool::CloseAllSessions(int error,
quic::QuicErrorCode quic_error) { … }
base::Value QuicSessionPool::QuicSessionPoolInfoToValue() const { … }
void QuicSessionPool::ClearCachedStatesInCryptoConfig(
const base::RepeatingCallback<bool(const GURL&)>& origin_filter) { … }
int QuicSessionPool::ConnectAndConfigureSocket(CompletionOnceCallback callback,
DatagramClientSocket* socket,
IPEndPoint addr,
handles::NetworkHandle network,
const SocketTag& socket_tag) { … }
void QuicSessionPool::FinishConnectAndConfigureSocket(
CompletionOnceCallback callback,
DatagramClientSocket* socket,
const SocketTag& socket_tag,
int rv) { … }
void QuicSessionPool::OnFinishConnectAndConfigureSocketError(
CompletionOnceCallback callback,
enum CreateSessionFailure error,
int rv) { … }
void QuicSessionPool::DoCallback(CompletionOnceCallback callback, int rv) { … }
int QuicSessionPool::ConfigureSocket(DatagramClientSocket* socket,
IPEndPoint addr,
handles::NetworkHandle network,
const SocketTag& socket_tag) { … }
handles::NetworkHandle QuicSessionPool::FindAlternateNetwork(
handles::NetworkHandle old_network) { … }
std::unique_ptr<DatagramClientSocket> QuicSessionPool::CreateSocket(
NetLog* net_log,
const NetLogSource& source) { … }
void QuicSessionPool::OnIPAddressChanged() { … }
void QuicSessionPool::OnNetworkConnected(handles::NetworkHandle network) { … }
void QuicSessionPool::OnNetworkDisconnected(handles::NetworkHandle network) { … }
void QuicSessionPool::OnNetworkSoonToDisconnect(
handles::NetworkHandle network) { … }
void QuicSessionPool::OnNetworkMadeDefault(handles::NetworkHandle network) { … }
void QuicSessionPool::OnTrustStoreChanged() { … }
void QuicSessionPool::OnCertVerifierChanged() { … }
void QuicSessionPool::set_is_quic_known_to_work_on_current_network(
bool is_quic_known_to_work_on_current_network) { … }
base::TimeDelta QuicSessionPool::GetTimeDelayForWaitingJob(
const QuicSessionKey& session_key) { … }
const std::set<std::string>& QuicSessionPool::GetDnsAliasesForSessionKey(
const QuicSessionKey& key) const { … }
void QuicSessionPool::ActivateSessionForTesting(
const url::SchemeHostPort& destination,
QuicChromiumClientSession* session) { … }
void QuicSessionPool::DeactivateSessionForTesting(
QuicChromiumClientSession* session) { … }
void QuicSessionPool::SetTimeDelayForWaitingJobForTesting(
base::TimeDelta delay) { … }
quic::ParsedQuicVersion QuicSessionPool::SelectQuicVersion(
const quic::ParsedQuicVersion& known_quic_version,
const ConnectionEndpointMetadata& metadata,
bool svcb_optional) const { … }
void QuicSessionPool::LogConnectionIpPooling(bool pooled) { … }
bool QuicSessionPool::HasMatchingIpSession(
const QuicSessionAliasKey& key,
const std::vector<IPEndPoint>& ip_endpoints,
const std::set<std::string>& aliases,
bool use_dns_aliases) { … }
void QuicSessionPool::OnJobComplete(Job* job, int rv) { … }
bool QuicSessionPool::HasActiveSession(
const QuicSessionKey& session_key) const { … }
bool QuicSessionPool::HasActiveJob(const QuicSessionKey& session_key) const { … }
int QuicSessionPool::CreateSessionSync(
QuicSessionAliasKey key,
quic::ParsedQuicVersion quic_version,
int cert_verify_flags,
bool require_confirmation,
IPEndPoint peer_address,
ConnectionEndpointMetadata metadata,
base::TimeTicks dns_resolution_start_time,
base::TimeTicks dns_resolution_end_time,
const NetLogWithSource& net_log,
raw_ptr<QuicChromiumClientSession>* session,
handles::NetworkHandle* network) { … }
int QuicSessionPool::CreateSessionAsync(
CompletionOnceCallback callback,
QuicSessionAliasKey key,
quic::ParsedQuicVersion quic_version,
int cert_verify_flags,
bool require_confirmation,
IPEndPoint peer_address,
ConnectionEndpointMetadata metadata,
base::TimeTicks dns_resolution_start_time,
base::TimeTicks dns_resolution_end_time,
const NetLogWithSource& net_log,
raw_ptr<QuicChromiumClientSession>* session,
handles::NetworkHandle* network) { … }
int QuicSessionPool::CreateSessionOnProxyStream(
CompletionOnceCallback callback,
QuicSessionAliasKey key,
quic::ParsedQuicVersion quic_version,
int cert_verify_flags,
bool require_confirmation,
IPEndPoint local_address,
IPEndPoint proxy_peer_address,
std::unique_ptr<QuicChromiumClientStream::Handle> proxy_stream,
std::string user_agent,
const NetLogWithSource& net_log,
raw_ptr<QuicChromiumClientSession>* session,
handles::NetworkHandle* network) { … }
void QuicSessionPool::FinishCreateSession(
CompletionOnceCallback callback,
QuicSessionAliasKey key,
quic::ParsedQuicVersion quic_version,
int cert_verify_flags,
bool require_confirmation,
IPEndPoint peer_address,
ConnectionEndpointMetadata metadata,
base::TimeTicks dns_resolution_start_time,
base::TimeTicks dns_resolution_end_time,
quic::QuicPacketLength session_max_packet_length,
const NetLogWithSource& net_log,
raw_ptr<QuicChromiumClientSession>* session,
handles::NetworkHandle* network,
std::unique_ptr<DatagramClientSocket> socket,
int rv) { … }
bool QuicSessionPool::CreateSessionHelper(
QuicSessionAliasKey key,
quic::ParsedQuicVersion quic_version,
int cert_verify_flags,
bool require_confirmation,
IPEndPoint peer_address,
ConnectionEndpointMetadata metadata,
base::TimeTicks dns_resolution_start_time,
base::TimeTicks dns_resolution_end_time,
quic::QuicPacketLength session_max_packet_length,
const NetLogWithSource& net_log,
raw_ptr<QuicChromiumClientSession>* session,
handles::NetworkHandle* network,
std::unique_ptr<DatagramClientSocket> socket) { … }
void QuicSessionPool::ActivateSession(const QuicSessionAliasKey& key,
QuicChromiumClientSession* session,
std::set<std::string> dns_aliases) { … }
void QuicSessionPool::MarkAllActiveSessionsGoingAway(
AllActiveSessionsGoingAwayReason reason) { … }
void QuicSessionPool::ConfigureInitialRttEstimate(
const quic::QuicServerId& server_id,
const NetworkAnonymizationKey& network_anonymization_key,
quic::QuicConfig* config) { … }
int64_t QuicSessionPool::GetServerNetworkStatsSmoothedRttInMicroseconds(
const quic::QuicServerId& server_id,
const NetworkAnonymizationKey& network_anonymization_key) const { … }
const base::TimeDelta* QuicSessionPool::GetServerNetworkStatsSmoothedRtt(
const quic::QuicServerId& server_id,
const NetworkAnonymizationKey& network_anonymization_key) const { … }
bool QuicSessionPool::WasQuicRecentlyBroken(
const QuicSessionKey& session_key) const { … }
void QuicSessionPool::InitializeMigrationOptions() { … }
void QuicSessionPool::InitializeCachedStateInCryptoConfig(
const CryptoClientConfigHandle& crypto_config_handle,
const quic::QuicServerId& server_id,
const std::unique_ptr<QuicServerInfo>& server_info) { … }
void QuicSessionPool::ProcessGoingAwaySession(
QuicChromiumClientSession* session,
const quic::QuicServerId& server_id,
bool session_was_active) { … }
void QuicSessionPool::ActivateAndMapSessionToAliasKey(
QuicChromiumClientSession* session,
QuicSessionAliasKey key,
std::set<std::string> dns_aliases) { … }
void QuicSessionPool::UnmapSessionFromSessionAliases(
QuicChromiumClientSession* session) { … }
std::unique_ptr<QuicSessionPool::CryptoClientConfigHandle>
QuicSessionPool::CreateCryptoConfigHandle(
const NetworkAnonymizationKey& network_anonymization_key) { … }
void QuicSessionPool::OnAllCryptoClientRefReleased(
QuicCryptoClientConfigMap::iterator& map_iterator) { … }
void QuicSessionPool::CollectDataOnPlatformNotification(
enum QuicPlatformNotification notification,
handles::NetworkHandle affected_network) const { … }
std::unique_ptr<QuicCryptoClientConfigHandle>
QuicSessionPool::GetCryptoConfigForTesting(
const NetworkAnonymizationKey& network_anonymization_key) { … }
bool QuicSessionPool::CryptoConfigCacheIsEmptyForTesting(
const quic::QuicServerId& server_id,
const NetworkAnonymizationKey& network_anonymization_key) { … }
}