1 // Copyright 2012 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_QUIC_SESSION_POOL_H_ 6 #define NET_QUIC_QUIC_SESSION_POOL_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <map> 12 #include <memory> 13 #include <optional> 14 #include <set> 15 #include <string> 16 #include <vector> 17 18 #include "base/containers/lru_cache.h" 19 #include "base/containers/unique_ptr_adapters.h" 20 #include "base/gtest_prod_util.h" 21 #include "base/memory/memory_pressure_monitor.h" 22 #include "base/memory/raw_ptr.h" 23 #include "base/memory/scoped_refptr.h" 24 #include "base/memory/weak_ptr.h" 25 #include "base/task/sequenced_task_runner.h" 26 #include "base/time/default_clock.h" 27 #include "base/time/default_tick_clock.h" 28 #include "base/time/tick_clock.h" 29 #include "base/time/time.h" 30 #include "base/values.h" 31 #include "net/base/address_list.h" 32 #include "net/base/completion_once_callback.h" 33 #include "net/base/connection_endpoint_metadata.h" 34 #include "net/base/host_port_pair.h" 35 #include "net/base/http_user_agent_settings.h" 36 #include "net/base/ip_endpoint.h" 37 #include "net/base/net_export.h" 38 #include "net/base/network_change_notifier.h" 39 #include "net/base/network_handle.h" 40 #include "net/base/proxy_server.h" 41 #include "net/base/session_usage.h" 42 #include "net/cert/cert_database.h" 43 #include "net/dns/public/secure_dns_policy.h" 44 #include "net/http/http_server_properties.h" 45 #include "net/http/http_stream_factory.h" 46 #include "net/log/net_log_with_source.h" 47 #include "net/quic/network_connection.h" 48 #include "net/quic/quic_chromium_client_session.h" 49 #include "net/quic/quic_clock_skew_detector.h" 50 #include "net/quic/quic_connectivity_monitor.h" 51 #include "net/quic/quic_context.h" 52 #include "net/quic/quic_crypto_client_config_handle.h" 53 #include "net/quic/quic_proxy_datagram_client_socket.h" 54 #include "net/quic/quic_session_alias_key.h" 55 #include "net/quic/quic_session_attempt.h" 56 #include "net/quic/quic_session_key.h" 57 #include "net/socket/client_socket_pool.h" 58 #include "net/spdy/multiplexed_session_creation_initiator.h" 59 #include "net/ssl/ssl_config_service.h" 60 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_client_session_cache.h" 61 #include "net/third_party/quiche/src/quiche/quic/core/deterministic_connection_id_generator.h" 62 #include "net/third_party/quiche/src/quiche/quic/core/quic_config.h" 63 #include "net/third_party/quiche/src/quiche/quic/core/quic_connection_id.h" 64 #include "net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.h" 65 #include "net/third_party/quiche/src/quiche/quic/core/quic_packets.h" 66 #include "net/third_party/quiche/src/quiche/quic/core/quic_server_id.h" 67 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h" 68 #include "url/scheme_host_port.h" 69 70 namespace base { 71 class Value; 72 } // namespace base 73 74 namespace quic { 75 class QuicAlarmFactory; 76 class QuicClock; 77 } // namespace quic 78 79 namespace quiche { 80 class QuicRandom; 81 } // namespace quiche 82 83 namespace net { 84 85 class CertVerifier; 86 class ClientSocketFactory; 87 class HostResolver; 88 class HttpServerProperties; 89 class NetLog; 90 class NetworkAnonymizationKey; 91 struct NetworkTrafficAnnotationTag; 92 class ProxyDelegate; 93 class QuicChromiumConnectionHelper; 94 class QuicCryptoClientStreamFactory; 95 class QuicServerInfo; 96 class QuicSessionPool; 97 class QuicContext; 98 class SCTAuditingDelegate; 99 class SocketPerformanceWatcherFactory; 100 class SocketTag; 101 class TransportSecurityState; 102 103 namespace test { 104 class QuicSessionPoolPeer; 105 } // namespace test 106 107 // Maximum number of not currently in use QuicCryptoClientConfig that can be 108 // stored in |recent_crypto_config_map_|. 109 // 110 // TODO(mmenke): Should figure out a reasonable value of this, using field 111 // trials. The optimal value may increase over time, as QUIC becomes more 112 // prevalent. Whether or not NetworkAnonymizationKeys end up including subframe 113 // URLs will also influence the ideal value. 114 const int kMaxRecentCryptoConfigs = 100; 115 116 enum QuicPlatformNotification { 117 NETWORK_CONNECTED, 118 NETWORK_MADE_DEFAULT, 119 NETWORK_DISCONNECTED, 120 NETWORK_SOON_TO_DISCONNECT, 121 NETWORK_IP_ADDRESS_CHANGED, 122 NETWORK_NOTIFICATION_MAX 123 }; 124 125 enum AllActiveSessionsGoingAwayReason { 126 kClockSkewDetected, 127 kIPAddressChanged, 128 kCertDBChanged, 129 kCertVerifierChanged 130 }; 131 132 enum CreateSessionFailure { 133 CREATION_ERROR_CONNECTING_SOCKET, 134 CREATION_ERROR_SETTING_RECEIVE_BUFFER, 135 CREATION_ERROR_SETTING_SEND_BUFFER, 136 CREATION_ERROR_SETTING_DO_NOT_FRAGMENT, 137 CREATION_ERROR_SETTING_RECEIVE_ECN, 138 CREATION_ERROR_MAX 139 }; 140 141 // Encapsulates a pending request for a QuicChromiumClientSession. 142 // If the request is still pending when it is destroyed, it will 143 // cancel the request with the pool. 144 class NET_EXPORT_PRIVATE QuicSessionRequest { 145 public: 146 explicit QuicSessionRequest(QuicSessionPool* pool); 147 148 QuicSessionRequest(const QuicSessionRequest&) = delete; 149 QuicSessionRequest& operator=(const QuicSessionRequest&) = delete; 150 151 ~QuicSessionRequest(); 152 153 // `cert_verify_flags` is bitwise OR'd of CertVerifier::VerifyFlags and it is 154 // passed to CertVerifier::Verify. 155 // `destination` will be resolved and resulting IPEndPoint used to open a 156 // quic::QuicConnection. This can be different than 157 // HostPortPair::FromURL(url). 158 // When `session_usage` is `kDestination`, any DNS aliases found in host 159 // resolution are stored in the `dns_aliases_by_session_key_` map. 160 int Request(url::SchemeHostPort destination, 161 quic::ParsedQuicVersion quic_version, 162 const ProxyChain& proxy_chain, 163 std::optional<NetworkTrafficAnnotationTag> proxy_annotation_tag, 164 const HttpUserAgentSettings* http_user_agent_settings, 165 SessionUsage session_usage, 166 PrivacyMode privacy_mode, 167 RequestPriority priority, 168 const SocketTag& socket_tag, 169 const NetworkAnonymizationKey& network_anonymization_key, 170 SecureDnsPolicy secure_dns_policy, 171 bool require_dns_https_alpn, 172 int cert_verify_flags, 173 const GURL& url, 174 const NetLogWithSource& net_log, 175 NetErrorDetails* net_error_details, 176 MultiplexedSessionCreationInitiator session_creation_initiator, 177 CompletionOnceCallback failed_on_default_network_callback, 178 CompletionOnceCallback callback); 179 180 // This function must be called after Request() returns ERR_IO_PENDING. 181 // Returns true if Request() requires host resolution and it hasn't completed 182 // yet. If true is returned, |callback| will run when host resolution 183 // completes. It will be called with the result after host resolution during 184 // the connection process. For example, if host resolution returns OK and then 185 // crypto handshake returns ERR_IO_PENDING, then |callback| will run with 186 // ERR_IO_PENDING. 187 bool WaitForHostResolution(CompletionOnceCallback callback); 188 189 // This function must be called after Request() returns ERR_IO_PENDING. 190 // Returns true if no QUIC session has been created yet. If true is returned, 191 // `callback` will be run when the QUIC session has been created and will be 192 // called with the result of OnCreateSessionComplete. For example, if session 193 // creation returned OK but CryptoConnect returns ERR_IO_PENDING then 194 // `callback` will be run with ERR_IO_PENDING. 195 bool WaitForQuicSessionCreation(CompletionOnceCallback callback); 196 197 // QuicSessionPool::Jobs may notify associated requests at two points in the 198 // connection process before completion: host resolution and session creation. 199 // The `Expect` methods below inform the request whether it should expect 200 // these notifications. 201 202 // Tells QuicSessionRequest that `QuicSessionPool::Job` will call 203 // `OnHostResolutionComplete()` in the future. Must be called before 204 // `WaitForHostResolution()` 205 void ExpectOnHostResolution(); 206 207 // Will be called by the associated `QuicSessionPool::Job` when host 208 // resolution completes asynchronously after Request(), if 209 // `ExpectOnHostResolution()` was called. This is called after the Job can 210 // make no further progress, and includes the result of that progress, perhaps 211 // `ERR_IO_PENDING`. 212 void OnHostResolutionComplete(int rv, 213 base::TimeTicks dns_resolution_start_time, 214 base::TimeTicks dns_resolution_end_time); 215 216 // Tells QuicSessionRequest that `QuicSessionPool::Job` will call 217 // `OnQuicSessionCreationComplete()` in the future. Must be called before 218 // `WaitForQuicSessionCreation()`. 219 void ExpectQuicSessionCreation(); 220 221 // Will be called by the associated `QuicSessionPool::Job` when session 222 // creation completes asynchronously after Request(), if 223 // `ExpectQuicSessionCreation` was called. 224 void OnQuicSessionCreationComplete(int rv); 225 226 void OnRequestComplete(int rv); 227 228 // Called when the original connection created on the default network for 229 // |this| fails and a new connection has been created on the alternate 230 // network. 231 void OnConnectionFailedOnDefaultNetwork(); 232 233 // Helper method that calls |pool_|'s GetTimeDelayForWaitingJob(). It 234 // returns the amount of time waiting job should be delayed. 235 base::TimeDelta GetTimeDelayForWaitingJob() const; 236 237 // If host resolution is underway, changes the priority of the host resolver 238 // request. 239 void SetPriority(RequestPriority priority); 240 241 // Releases the handle to the QUIC session retrieved as a result of Request(). 242 std::unique_ptr<QuicChromiumClientSession::Handle> ReleaseSessionHandle(); 243 244 // Sets |session_|. 245 void SetSession(std::unique_ptr<QuicChromiumClientSession::Handle> session); 246 net_error_details()247 NetErrorDetails* net_error_details() { return net_error_details_; } 248 session_key()249 const QuicSessionKey& session_key() const { return session_key_; } 250 net_log()251 const NetLogWithSource& net_log() const { return net_log_; } 252 dns_resolution_start_time()253 base::TimeTicks dns_resolution_start_time() const { 254 return dns_resolution_start_time_; 255 } dns_resolution_end_time()256 base::TimeTicks dns_resolution_end_time() const { 257 return dns_resolution_end_time_; 258 } 259 260 private: 261 raw_ptr<QuicSessionPool> pool_; 262 QuicSessionKey session_key_; 263 NetLogWithSource net_log_; 264 CompletionOnceCallback callback_; 265 CompletionOnceCallback failed_on_default_network_callback_; 266 raw_ptr<NetErrorDetails> net_error_details_; // Unowned. 267 std::unique_ptr<QuicChromiumClientSession::Handle> session_; 268 269 base::TimeTicks dns_resolution_start_time_; 270 base::TimeTicks dns_resolution_end_time_; 271 272 // Set in Request(). If true, then OnHostResolutionComplete() is expected to 273 // be called in the future. 274 bool expect_on_host_resolution_ = false; 275 276 bool expect_on_quic_session_creation_ = false; 277 // Callback passed to WaitForHostResolution(). 278 CompletionOnceCallback host_resolution_callback_; 279 280 CompletionOnceCallback create_session_callback_; 281 }; 282 283 // Represents a single QUIC endpoint and the information necessary to attempt 284 // a QUIC session. 285 struct NET_EXPORT_PRIVATE QuicEndpoint { 286 QuicEndpoint(quic::ParsedQuicVersion quic_version, 287 IPEndPoint ip_endpoint, 288 ConnectionEndpointMetadata metadata); 289 ~QuicEndpoint(); 290 291 quic::ParsedQuicVersion quic_version = quic::ParsedQuicVersion::Unsupported(); 292 IPEndPoint ip_endpoint; 293 ConnectionEndpointMetadata metadata; 294 295 base::Value::Dict ToValue() const; 296 }; 297 298 // Manages a pool of QuicChromiumClientSessions. 299 class NET_EXPORT_PRIVATE QuicSessionPool 300 : public NetworkChangeNotifier::IPAddressObserver, 301 public NetworkChangeNotifier::NetworkObserver, 302 public CertDatabase::Observer, 303 public CertVerifier::Observer { 304 public: 305 QuicSessionPool( 306 NetLog* net_log, 307 HostResolver* host_resolver, 308 SSLConfigService* ssl_config_service, 309 ClientSocketFactory* client_socket_factory, 310 HttpServerProperties* http_server_properties, 311 CertVerifier* cert_verifier, 312 TransportSecurityState* transport_security_state, 313 ProxyDelegate* proxy_delegate, 314 SCTAuditingDelegate* sct_auditing_delegate, 315 SocketPerformanceWatcherFactory* socket_performance_watcher_factory, 316 QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory, 317 QuicContext* context); 318 319 QuicSessionPool(const QuicSessionPool&) = delete; 320 QuicSessionPool& operator=(const QuicSessionPool&) = delete; 321 322 ~QuicSessionPool() override; 323 324 // Returns true if there is an existing session for |session_key| or if the 325 // request can be pooled to an existing session to the IP address of 326 // |destination|. 327 bool CanUseExistingSession(const QuicSessionKey& session_key, 328 const url::SchemeHostPort& destination) const; 329 330 // Returns a session for `session_key` or if the request can be pooled to an 331 // existing session to the IP address of `destination`. 332 QuicChromiumClientSession* FindExistingSession( 333 const QuicSessionKey& session_key, 334 const url::SchemeHostPort& destination) const; 335 336 // Returns true when an existing session can be used for `destination` that 337 // is resolved with `service_endpoint`. 338 bool HasMatchingIpSessionForServiceEndpoint( 339 const QuicSessionAliasKey& session_alias_key, 340 const ServiceEndpoint& service_endpoint, 341 const std::set<std::string>& dns_aliases, 342 bool use_dns_aliases); 343 344 // Requests a QuicChromiumClientSession to |host_port_pair|, a handle for 345 // which will be owned by |request|. 346 // If a matching session already exists, this method will return OK. If no 347 // matching session exists, this will return ERR_IO_PENDING and will invoke 348 // OnRequestComplete asynchronously. 349 // When |use_dns_aliases| is true, any DNS aliases found in host resolution 350 // are stored in the |dns_aliases_by_session_key_| map. |use_dns_aliases| 351 // should be false in the case of a proxy. 352 // When the `proxy_chain` in the session key is not direct, 353 // `proxy_annotation_tag` must be set. 354 // This method is virtual to facilitate mocking for tests. 355 virtual int RequestSession( 356 const QuicSessionKey& session_key, 357 url::SchemeHostPort destination, 358 quic::ParsedQuicVersion quic_version, 359 std::optional<NetworkTrafficAnnotationTag> proxy_annotation_tag, 360 MultiplexedSessionCreationInitiator session_creation_initiator, 361 const HttpUserAgentSettings* http_user_agent_settings, 362 RequestPriority priority, 363 bool use_dns_aliases, 364 int cert_verify_flags, 365 const GURL& url, 366 const NetLogWithSource& net_log, 367 QuicSessionRequest* request); 368 369 // Creates a session attempt for `session_key` with `quic_endpoint`. There 370 // should be no matching session for `session_key`. This doesn't support 371 // proxies. 372 // *NOTE*: This method must not be used simultaneously with 373 // QuicSessionRequest for the same `session_key`. 374 std::unique_ptr<QuicSessionAttempt> CreateSessionAttempt( 375 QuicSessionAttempt::Delegate* delegate, 376 const QuicSessionKey& session_key, 377 QuicEndpoint quic_endpoint, 378 int cert_verify_flags, 379 base::TimeTicks dns_resolution_start_time, 380 base::TimeTicks dns_resolution_end_time, 381 bool use_dns_aliases, 382 std::set<std::string> dns_aliases, 383 MultiplexedSessionCreationInitiator session_creation_initiator); 384 385 // Called by a session when it is going away and no more streams should be 386 // created on it. 387 void OnSessionGoingAway(QuicChromiumClientSession* session); 388 389 // Called by a session after it shuts down. 390 void OnSessionClosed(QuicChromiumClientSession* session); 391 392 // Called by a session when it blackholes after the handshake is confirmed. 393 void OnBlackholeAfterHandshakeConfirmed(QuicChromiumClientSession* session); 394 395 // Cancels a pending request. Does nothing if the request is not active. 396 // This method is virtual to facilitate mocking for tests. 397 virtual void CancelRequest(QuicSessionRequest* request); 398 399 // Sets priority of a request. 400 void SetRequestPriority(QuicSessionRequest* request, 401 RequestPriority priority); 402 403 // Closes all current sessions with specified network, QUIC error codes. 404 // It sends connection close packet when closing connections. 405 void CloseAllSessions(int error, quic::QuicErrorCode quic_error); 406 407 base::Value QuicSessionPoolInfoToValue() const; 408 409 // Delete cached state objects in |crypto_config_|. If |origin_filter| is not 410 // null, only objects on matching origins will be deleted. 411 void ClearCachedStatesInCryptoConfig( 412 const base::RepeatingCallback<bool(const GURL&)>& origin_filter); 413 414 // Helper method that connects a DatagramClientSocket. Socket is 415 // bound to the default network if the |network| param is 416 // handles::kInvalidNetworkHandle. This method calls 417 // DatagramClientSocket::ConnectAsync and always completes asynchronously, 418 // implicitly returning ERR_IO_PENDING. 419 void ConnectAndConfigureSocket(CompletionOnceCallback callback, 420 DatagramClientSocket* socket, 421 IPEndPoint addr, 422 handles::NetworkHandle network, 423 const SocketTag& socket_tag); 424 425 // Helper method that configures a DatagramClientSocket once 426 // DatagramClientSocket::ConnectAsync completes. Posts a task to run 427 // `callback` with a net_error code. 428 // This method is virtual to facilitate mocking for tests. 429 virtual void FinishConnectAndConfigureSocket(CompletionOnceCallback callback, 430 DatagramClientSocket* socket, 431 const SocketTag& socket_tag, 432 int rv); 433 434 void OnFinishConnectAndConfigureSocketError(CompletionOnceCallback callback, 435 enum CreateSessionFailure error, 436 int rv); 437 438 void DoCallback(CompletionOnceCallback callback, int rv); 439 440 // Helper method that configures a DatagramClientSocket. Socket is 441 // bound to the default network if the |network| param is 442 // handles::kInvalidNetworkHandle. This method calls 443 // DatagramClientSocket::Connect and completes synchronously. Returns 444 // net_error code. 445 // TODO(liza): Remove this once QuicSessionPool::Job calls 446 // ConnectAndConfigureSocket. 447 int ConfigureSocket(DatagramClientSocket* socket, 448 IPEndPoint addr, 449 handles::NetworkHandle network, 450 const SocketTag& socket_tag); 451 452 // Finds an alternative to |old_network| from the platform's list of connected 453 // networks. Returns handles::kInvalidNetworkHandle if no 454 // alternative is found. 455 handles::NetworkHandle FindAlternateNetwork( 456 handles::NetworkHandle old_network); 457 458 // Creates a datagram socket. |source| is the NetLogSource for the entity 459 // trying to create the socket, if it has one. 460 std::unique_ptr<DatagramClientSocket> CreateSocket( 461 NetLog* net_log, 462 const NetLogSource& source); 463 464 // NetworkChangeNotifier::IPAddressObserver methods: 465 466 // Until the servers support roaming, close all connections when the local 467 // IP address changes. 468 void OnIPAddressChanged() override; 469 470 // NetworkChangeNotifier::NetworkObserver methods: 471 void OnNetworkConnected(handles::NetworkHandle network) override; 472 void OnNetworkDisconnected(handles::NetworkHandle network) override; 473 void OnNetworkSoonToDisconnect(handles::NetworkHandle network) override; 474 void OnNetworkMadeDefault(handles::NetworkHandle network) override; 475 476 // CertDatabase::Observer methods: 477 478 // We close all sessions when certificate database is changed. 479 void OnTrustStoreChanged() override; 480 481 // CertVerifier::Observer: 482 // We close all sessions when certificate verifier settings have changed. 483 void OnCertVerifierChanged() override; 484 has_quic_ever_worked_on_current_network()485 bool has_quic_ever_worked_on_current_network() const { 486 return has_quic_ever_worked_on_current_network_; 487 } 488 allow_server_migration()489 bool allow_server_migration() const { return params_.allow_server_migration; } 490 491 // Returns true is gQUIC 0-RTT is disabled from quic_context. gquic_zero_rtt_disabled()492 bool gquic_zero_rtt_disabled() const { 493 return params_.disable_gquic_zero_rtt; 494 } 495 496 // Returns true if QuicSessionPool is configured to report incoming ECN marks. report_ecn()497 bool report_ecn() const { 498 return report_ecn_; 499 } 500 501 void set_has_quic_ever_worked_on_current_network( 502 bool has_quic_ever_worked_on_current_network); 503 504 // It returns the amount of time waiting job should be delayed. 505 base::TimeDelta GetTimeDelayForWaitingJob(const QuicSessionKey& session_key); 506 helper()507 QuicChromiumConnectionHelper* helper() { return helper_.get(); } 508 alarm_factory()509 quic::QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); } 510 default_network()511 handles::NetworkHandle default_network() const { return default_network_; } 512 513 // Returns the stored DNS aliases for the session key. 514 const std::set<std::string>& GetDnsAliasesForSessionKey( 515 const QuicSessionKey& key) const; 516 CountActiveSessions()517 int CountActiveSessions() { return active_sessions_.size(); } 518 519 // Inject a QUIC session for testing various edge cases. 520 void ActivateSessionForTesting( 521 std::unique_ptr<QuicChromiumClientSession> new_session); 522 523 void DeactivateSessionForTesting(QuicChromiumClientSession* session); 524 525 // Set a time delay for waiting job for testing. 526 void SetTimeDelayForWaitingJobForTesting(base::TimeDelta delay); 527 528 // Returns the QUIC version that would be used with an endpoint associated 529 // with `metadata`, or `quic::ParsedQuicVersion::Unsupported()` if the 530 // endpoint cannot be used with QUIC. 531 quic::ParsedQuicVersion SelectQuicVersion( 532 const quic::ParsedQuicVersion& known_quic_version, 533 const ConnectionEndpointMetadata& metadata, 534 bool svcb_optional) const; 535 536 private: 537 class Job; 538 class DirectJob; 539 class ProxyJob; 540 class QuicCryptoClientConfigOwner; 541 class CryptoClientConfigHandle; 542 friend class QuicSessionAttempt; 543 friend class MockQuicSessionPool; 544 friend class test::QuicSessionPoolPeer; 545 546 using SessionMap = 547 std::map<QuicSessionKey, 548 raw_ptr<QuicChromiumClientSession, CtnExperimental>>; 549 using SessionIdSet = std::set<std::unique_ptr<QuicChromiumClientSession>, 550 base::UniquePtrComparator>; 551 using AliasSet = std::set<QuicSessionAliasKey>; 552 using SessionAliasMap = std::map<QuicChromiumClientSession*, AliasSet>; 553 using SessionSet = 554 std::set<raw_ptr<QuicChromiumClientSession, SetExperimental>>; 555 using IPAliasMap = std::map<IPEndPoint, SessionSet>; 556 using SessionPeerIPMap = std::map<QuicChromiumClientSession*, IPEndPoint>; 557 using JobMap = std::map<QuicSessionKey, std::unique_ptr<Job>>; 558 using DnsAliasesBySessionKeyMap = 559 std::map<QuicSessionKey, std::set<std::string>>; 560 using QuicCryptoClientConfigMap = 561 std::map<NetworkAnonymizationKey, 562 std::unique_ptr<QuicCryptoClientConfigOwner>>; 563 564 // Records whether an active session already exists for a given IP address 565 // during connection. 566 static void LogConnectionIpPooling(bool pooled); 567 568 bool HasMatchingIpSession(const QuicSessionAliasKey& key, 569 const std::vector<IPEndPoint>& ip_endpoints, 570 const std::set<std::string>& aliases, 571 bool use_dns_aliases); 572 // Returns true if IP matching can be waived when trying to send requests to 573 // |destination| on |session|. 574 bool CanWaiveIpMatching(const url::SchemeHostPort& destination, 575 QuicChromiumClientSession* session) const; 576 void OnJobComplete(Job* job, 577 std::optional<base::TimeTicks> proxy_connect_start_time, 578 int rv); 579 bool HasActiveSession(const QuicSessionKey& session_key) const; 580 bool HasActiveJob(const QuicSessionKey& session_key) const; 581 int CreateSessionSync(QuicSessionAliasKey key, 582 quic::ParsedQuicVersion quic_version, 583 int cert_verify_flags, 584 bool require_confirmation, 585 IPEndPoint peer_address, 586 ConnectionEndpointMetadata metadata, 587 base::TimeTicks dns_resolution_start_time, 588 base::TimeTicks dns_resolution_end_time, 589 const NetLogWithSource& net_log, 590 raw_ptr<QuicChromiumClientSession>* session, 591 handles::NetworkHandle* network, 592 MultiplexedSessionCreationInitiator preconnet_origin); 593 // Note: QUIC session create methods that complete asynchronously, we can't 594 // pass raw pointers as parameters because we can't guarantee that these raw 595 // pointers outlive `this` since we use nested callbacks in these methods. See 596 // the commit description of crrev.com/c/5858326. 597 using CreateSessionCallback = base::OnceCallback<void( 598 base::expected<QuicSessionAttempt::CreateSessionResult, int>)>; 599 int CreateSessionAsync( 600 CreateSessionCallback callback, 601 QuicSessionAliasKey key, 602 quic::ParsedQuicVersion quic_version, 603 int cert_verify_flags, 604 bool require_confirmation, 605 IPEndPoint peer_address, 606 ConnectionEndpointMetadata metadata, 607 base::TimeTicks dns_resolution_start_time, 608 base::TimeTicks dns_resolution_end_time, 609 const NetLogWithSource& net_log, 610 handles::NetworkHandle network, 611 MultiplexedSessionCreationInitiator session_creation_initiator); 612 int CreateSessionOnProxyStream( 613 CreateSessionCallback callback, 614 QuicSessionAliasKey key, 615 quic::ParsedQuicVersion quic_version, 616 int cert_verify_flags, 617 bool require_confirmation, 618 IPEndPoint local_address, 619 IPEndPoint proxy_peer_address, 620 std::unique_ptr<QuicChromiumClientStream::Handle> proxy_stream, 621 std::string user_agent, 622 const NetLogWithSource& net_log, 623 handles::NetworkHandle network); 624 void FinishCreateSession( 625 CreateSessionCallback callback, 626 QuicSessionAliasKey key, 627 quic::ParsedQuicVersion quic_version, 628 int cert_verify_flags, 629 bool require_confirmation, 630 IPEndPoint peer_address, 631 ConnectionEndpointMetadata metadata, 632 base::TimeTicks dns_resolution_start_time, 633 base::TimeTicks dns_resolution_end_time, 634 quic::QuicPacketLength session_max_packet_length, 635 const NetLogWithSource& net_log, 636 handles::NetworkHandle network, 637 std::unique_ptr<DatagramClientSocket> socket, 638 MultiplexedSessionCreationInitiator session_creation_initiator, 639 int rv); 640 base::expected<QuicSessionAttempt::CreateSessionResult, int> 641 CreateSessionHelper( 642 QuicSessionAliasKey key, 643 quic::ParsedQuicVersion quic_version, 644 int cert_verify_flags, 645 bool require_confirmation, 646 IPEndPoint peer_address, 647 ConnectionEndpointMetadata metadata, 648 base::TimeTicks dns_resolution_start_time, 649 base::TimeTicks dns_resolution_end_time, 650 quic::QuicPacketLength session_max_packet_length, 651 const NetLogWithSource& net_log, 652 handles::NetworkHandle network, 653 std::unique_ptr<DatagramClientSocket> socket, 654 MultiplexedSessionCreationInitiator session_creation_initiator); 655 656 // Called when the Job for the given key has created and confirmed a session. 657 void ActivateSession(const QuicSessionAliasKey& key, 658 QuicChromiumClientSession* session, 659 std::set<std::string> dns_aliases); 660 661 // Go away all active sessions. May disable session's connectivity monitoring 662 // based on the |reason|. 663 void MarkAllActiveSessionsGoingAway(AllActiveSessionsGoingAwayReason reason); 664 665 void ConfigureInitialRttEstimate( 666 const quic::QuicServerId& server_id, 667 const NetworkAnonymizationKey& network_anonymization_key, 668 quic::QuicConfig* config); 669 670 // Returns |srtt| in micro seconds from ServerNetworkStats. Returns 0 if there 671 // is no |http_server_properties_| or if |http_server_properties_| doesn't 672 // have ServerNetworkStats for the given |server_id|. 673 int64_t GetServerNetworkStatsSmoothedRttInMicroseconds( 674 const quic::QuicServerId& server_id, 675 const NetworkAnonymizationKey& network_anonymization_key) const; 676 677 // Returns |srtt| from ServerNetworkStats. Returns null if there 678 // is no |http_server_properties_| or if |http_server_properties_| doesn't 679 // have ServerNetworkStats for the given |server_id|. 680 const base::TimeDelta* GetServerNetworkStatsSmoothedRtt( 681 const quic::QuicServerId& server_id, 682 const NetworkAnonymizationKey& network_anonymization_key) const; 683 684 // Helper methods. 685 bool WasQuicRecentlyBroken(const QuicSessionKey& session_key) const; 686 687 // Helper method to initialize the following migration options and check 688 // pre-requisites: 689 // - |params_.migrate_sessions_on_network_change_v2| 690 // - |params_.migrate_sessions_early_v2| 691 // - |params_.migrate_idle_sessions| 692 // - |params_.retry_on_alternate_network_before_handshake| 693 // If pre-requisites are not met, turn off the corresponding options. 694 void InitializeMigrationOptions(); 695 696 // Initializes the cached state associated with |server_id| in 697 // |crypto_config_| with the information in |server_info|. 698 void InitializeCachedStateInCryptoConfig( 699 const CryptoClientConfigHandle& crypto_config_handle, 700 const quic::QuicServerId& server_id, 701 const std::unique_ptr<QuicServerInfo>& server_info); 702 703 void ProcessGoingAwaySession(QuicChromiumClientSession* session, 704 const quic::QuicServerId& server_id, 705 bool was_session_active); 706 707 // Insert the session to `active_sessions_`, and insert the given alias `key` 708 // in the AliasSet for the given `session` in the map `session_aliases_`, and 709 // add the given `dns_aliases` for `key.session_key()` in 710 // `dns_aliases_by_session_key_`. 711 void ActivateAndMapSessionToAliasKey(QuicChromiumClientSession* session, 712 QuicSessionAliasKey key, 713 std::set<std::string> dns_aliases); 714 715 // For all alias keys for `session` in `session_aliases_`, erase the 716 // corresponding DNS aliases in `dns_aliases_by_session_key_`. Then erase 717 // `session` from `session_aliases_`. 718 void UnmapSessionFromSessionAliases(QuicChromiumClientSession* session); 719 720 // Creates a CreateCryptoConfigHandle for the specified 721 // NetworkAnonymizationKey. If there's already a corresponding entry in 722 // |active_crypto_config_map_|, reuses it. If there's a corresponding entry in 723 // |recent_crypto_config_map_|, promotes it to |active_crypto_config_map_| and 724 // then reuses it. Otherwise, creates a new entry in 725 // |active_crypto_config_map_|. 726 std::unique_ptr<CryptoClientConfigHandle> CreateCryptoConfigHandle( 727 const NetworkAnonymizationKey& network_anonymization_key); 728 729 // Salled when the indicated member of |active_crypto_config_map_| has no 730 // outstanding references. The QuicCryptoClientConfigOwner is then moved to 731 // |recent_crypto_config_map_|, an MRU cache. 732 void OnAllCryptoClientRefReleased( 733 QuicCryptoClientConfigMap::iterator& map_iterator); 734 735 // Called when a network change happens. 736 // Collect platform notification metrics, and if the change affects the 737 // original default network interface, collect connectivity degradation 738 // metrics from |connectivity_monitor_| and add to histograms. 739 void CollectDataOnPlatformNotification( 740 enum QuicPlatformNotification notification, 741 handles::NetworkHandle affected_network) const; 742 743 std::unique_ptr<QuicCryptoClientConfigHandle> GetCryptoConfigForTesting( 744 const NetworkAnonymizationKey& network_anonymization_key); 745 746 bool CryptoConfigCacheIsEmptyForTesting( 747 const quic::QuicServerId& server_id, 748 const NetworkAnonymizationKey& network_anonymization_key); 749 supported_versions()750 const quic::ParsedQuicVersionVector& supported_versions() const { 751 return params_.supported_versions; 752 } 753 754 // Whether QUIC is known to have ever worked on current network. This is true 755 // when QUIC is expected to work in general, rather than whether QUIC was 756 // broken / recently broken when used with a particular server. That 757 // information is stored in the broken alternative service map in 758 // HttpServerProperties. 759 bool has_quic_ever_worked_on_current_network_ = false; 760 761 NetLogWithSource net_log_; 762 const raw_ptr<HostResolver> host_resolver_; 763 const raw_ptr<ClientSocketFactory> client_socket_factory_; 764 const raw_ptr<HttpServerProperties> http_server_properties_; 765 const raw_ptr<CertVerifier> cert_verifier_; 766 const raw_ptr<TransportSecurityState> transport_security_state_; 767 const raw_ptr<ProxyDelegate> proxy_delegate_; 768 const raw_ptr<SCTAuditingDelegate> sct_auditing_delegate_; 769 const raw_ptr<QuicCryptoClientStreamFactory> 770 quic_crypto_client_stream_factory_; 771 const raw_ptr<quic::QuicRandom> random_generator_; // Unowned. 772 const raw_ptr<const quic::QuicClock> clock_; // Unowned. 773 QuicParams params_; 774 QuicClockSkewDetector clock_skew_detector_; 775 776 // Factory which is used to create socket performance watcher. A new watcher 777 // is created for every QUIC connection. 778 // |socket_performance_watcher_factory_| may be null. 779 const raw_ptr<SocketPerformanceWatcherFactory> 780 socket_performance_watcher_factory_; 781 782 // The helper used for all connections. 783 std::unique_ptr<QuicChromiumConnectionHelper> helper_; 784 785 // The alarm factory used for all connections. 786 std::unique_ptr<quic::QuicAlarmFactory> alarm_factory_; 787 788 // Contains owning pointers to all sessions that currently exist. 789 SessionIdSet all_sessions_; 790 // Contains non-owning pointers to currently active session 791 // (not going away session, once they're implemented). 792 SessionMap active_sessions_; 793 // Map from session to set of aliases that this session is known by. 794 SessionAliasMap session_aliases_; 795 // Map from IP address to sessions which are connected to this address. 796 IPAliasMap ip_aliases_; 797 // Map from session to its original peer IP address. 798 SessionPeerIPMap session_peer_ip_; 799 800 // Origins which have gone away recently. 801 AliasSet gone_away_aliases_; 802 803 // A map of DNS alias vectors by session keys. 804 DnsAliasesBySessionKeyMap dns_aliases_by_session_key_; 805 806 // When a QuicCryptoClientConfig is in use, it has one or more live 807 // CryptoClientConfigHandles, and is stored in |active_crypto_config_map_|. 808 // Once all the handles are deleted, it's moved to 809 // |recent_crypto_config_map_|. If reused before it is evicted from LRUCache, 810 // it will be removed from the cache and return to the active config map. 811 // These two maps should never both have entries with the same 812 // NetworkAnonymizationKey. 813 QuicCryptoClientConfigMap active_crypto_config_map_; 814 base::LRUCache<NetworkAnonymizationKey, 815 std::unique_ptr<QuicCryptoClientConfigOwner>> 816 recent_crypto_config_map_; 817 818 const quic::QuicConfig config_; 819 820 JobMap active_jobs_; 821 822 // PING timeout for connections. 823 quic::QuicTime::Delta ping_timeout_; 824 quic::QuicTime::Delta reduced_ping_timeout_; 825 826 // Timeout for how long the wire can have no retransmittable packets. 827 quic::QuicTime::Delta retransmittable_on_wire_timeout_; 828 829 // If more than |yield_after_packets_| packets have been read or more than 830 // |yield_after_duration_| time has passed, then 831 // QuicChromiumPacketReader::StartReading() yields by doing a PostTask(). 832 int yield_after_packets_; 833 quic::QuicTime::Delta yield_after_duration_; 834 835 // If |migrate_sessions_early_v2_| is true, tracks the current default 836 // network, and is updated OnNetworkMadeDefault. 837 // Otherwise, always set to NetworkChangeNotifier::kInvalidNetwork. 838 handles::NetworkHandle default_network_; 839 840 // Local address of socket that was created in CreateSession. 841 IPEndPoint local_address_; 842 // True if we need to check HttpServerProperties if QUIC was supported last 843 // time. 844 bool need_to_check_persisted_supports_quic_ = true; 845 bool prefer_aes_gcm_recorded_ = false; 846 847 NetworkConnection network_connection_; 848 849 QuicConnectivityMonitor connectivity_monitor_; 850 851 scoped_refptr<base::SequencedTaskRunner> task_runner_ = nullptr; 852 853 // This needs to be below `task_runner_`, since in some tests, it often points 854 // to a TickClock owned by the TestMockTimeTaskRunner that `task_runner_` 855 // owners a reference to. 856 raw_ptr<const base::TickClock> tick_clock_ = nullptr; 857 858 const raw_ptr<SSLConfigService> ssl_config_service_; 859 860 // Whether NetworkAnonymizationKeys should be used for 861 // `active_crypto_config_map_`. If false, there will just be one config with 862 // an empty NetworkAnonymizationKey. Whether QuicSessionAliasKeys all have an 863 // empty NAK is based on whether socket pools are respecting NAKs, but whether 864 // those NAKs are also used when accessing `active_crypto_config_map_` is also 865 // gated this, which is set based on whether HttpServerProperties is 866 // respecting NAKs, as that data is fed into the crypto config map using the 867 // corresponding NAK. 868 const bool use_network_anonymization_key_for_crypto_configs_; 869 870 // If true, sessions created by this pool will read ECN marks from QUIC 871 // sockets and send them to the peer. 872 const bool report_ecn_; 873 874 // If true, skip DNS resolution for a hostname if the ORIGIN frame received on 875 // an active session encompasses that hostname. 876 const bool skip_dns_with_origin_frame_; 877 878 // If true, a request will be sent on the existing session iff the hostname 879 // matches the certificate presented during the handshake. 880 const bool ignore_ip_matching_when_finding_existing_sessions_; 881 882 quic::DeterministicConnectionIdGenerator connection_id_generator_{ 883 quic::kQuicDefaultConnectionIdLength}; 884 885 std::optional<base::TimeDelta> time_delay_for_waiting_job_for_testing_; 886 887 base::WeakPtrFactory<QuicSessionPool> weak_factory_{this}; 888 }; 889 890 // Refcounted class that owns quic::QuicCryptoClientConfig and tracks how many 891 // consumers are using it currently. When the last reference is freed, the 892 // QuicCryptoClientConfigHandle informs the owning QuicSessionPool, moves it 893 // into an MRU cache. 894 class QuicSessionPool::QuicCryptoClientConfigOwner { 895 public: 896 QuicCryptoClientConfigOwner( 897 std::unique_ptr<quic::ProofVerifier> proof_verifier, 898 std::unique_ptr<quic::QuicClientSessionCache> session_cache, 899 QuicSessionPool* quic_session_pool); 900 901 QuicCryptoClientConfigOwner(const QuicCryptoClientConfigOwner&) = delete; 902 QuicCryptoClientConfigOwner& operator=(const QuicCryptoClientConfigOwner&) = 903 delete; 904 905 ~QuicCryptoClientConfigOwner(); 906 config()907 quic::QuicCryptoClientConfig* config() { return &config_; } 908 num_refs()909 int num_refs() const { return num_refs_; } 910 quic_session_pool()911 QuicSessionPool* quic_session_pool() { return quic_session_pool_; } 912 913 void OnMemoryPressure( 914 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level); 915 916 private: 917 friend class CryptoClientConfigHandle; 918 919 // Simple ref counting. Not using scoped_refptr allows for both keeping around 920 // an MRU cache of 0-reference objects, and DCHECKing that there are no 921 // outstanding referenced QuicCryptoClientConfigOwner on destruction. Private 922 // so that only CryptoClientConfigHandle can add and remove refs. 923 AddRef()924 void AddRef() { num_refs_++; } 925 ReleaseRef()926 void ReleaseRef() { 927 DCHECK_GT(num_refs_, 0); 928 num_refs_--; 929 } 930 931 int num_refs_ = 0; 932 quic::QuicCryptoClientConfig config_; 933 raw_ptr<base::Clock> clock_; 934 std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; 935 const raw_ptr<QuicSessionPool> quic_session_pool_; 936 }; 937 938 // Class that owns a reference to a QuicCryptoClientConfigOwner. Handles 939 // incrementing the refcount on construction, and decrementing it on 940 // destruction. 941 class QuicSessionPool::CryptoClientConfigHandle 942 : public QuicCryptoClientConfigHandle { 943 public: 944 explicit CryptoClientConfigHandle( 945 const QuicCryptoClientConfigMap::iterator& map_iterator); 946 CryptoClientConfigHandle(const CryptoClientConfigHandle & other)947 CryptoClientConfigHandle(const CryptoClientConfigHandle& other) 948 : CryptoClientConfigHandle(other.map_iterator_) {} 949 950 CryptoClientConfigHandle& operator=(const CryptoClientConfigHandle&) = delete; 951 952 ~CryptoClientConfigHandle() override; 953 954 quic::QuicCryptoClientConfig* GetConfig() const override; 955 956 private: 957 QuicCryptoClientConfigMap::iterator map_iterator_; 958 }; 959 960 } // namespace net 961 962 #endif // NET_QUIC_QUIC_SESSION_POOL_H_ 963