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