• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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