xref: /aosp_15_r20/external/cronet/net/quic/quic_session_pool.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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