xref: /aosp_15_r20/external/cronet/net/spdy/spdy_session_pool.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef NET_SPDY_SPDY_SESSION_POOL_H_
6*6777b538SAndroid Build Coastguard Worker #define NET_SPDY_SPDY_SESSION_POOL_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include <list>
11*6777b538SAndroid Build Coastguard Worker #include <map>
12*6777b538SAndroid Build Coastguard Worker #include <memory>
13*6777b538SAndroid Build Coastguard Worker #include <optional>
14*6777b538SAndroid Build Coastguard Worker #include <set>
15*6777b538SAndroid Build Coastguard Worker #include <string>
16*6777b538SAndroid Build Coastguard Worker #include <vector>
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h"
20*6777b538SAndroid Build Coastguard Worker #include "net/base/host_port_pair.h"
21*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_endpoint.h"
22*6777b538SAndroid Build Coastguard Worker #include "net/base/load_timing_info.h"
23*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
24*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h"
25*6777b538SAndroid Build Coastguard Worker #include "net/base/network_change_notifier.h"
26*6777b538SAndroid Build Coastguard Worker #include "net/base/proxy_server.h"
27*6777b538SAndroid Build Coastguard Worker #include "net/dns/public/host_resolver_results.h"
28*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_source.h"
29*6777b538SAndroid Build Coastguard Worker #include "net/proxy_resolution/proxy_config.h"
30*6777b538SAndroid Build Coastguard Worker #include "net/socket/connect_job.h"
31*6777b538SAndroid Build Coastguard Worker #include "net/socket/ssl_client_socket.h"
32*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_session_key.h"
33*6777b538SAndroid Build Coastguard Worker #include "net/ssl/ssl_config_service.h"
34*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
35*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
36*6777b538SAndroid Build Coastguard Worker 
37*6777b538SAndroid Build Coastguard Worker namespace net {
38*6777b538SAndroid Build Coastguard Worker 
39*6777b538SAndroid Build Coastguard Worker class ClientSocketHandle;
40*6777b538SAndroid Build Coastguard Worker class HostResolver;
41*6777b538SAndroid Build Coastguard Worker class HttpServerProperties;
42*6777b538SAndroid Build Coastguard Worker class NetLogWithSource;
43*6777b538SAndroid Build Coastguard Worker class NetworkQualityEstimator;
44*6777b538SAndroid Build Coastguard Worker class SpdySession;
45*6777b538SAndroid Build Coastguard Worker class StreamSocket;
46*6777b538SAndroid Build Coastguard Worker class TransportSecurityState;
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker // This is a very simple pool for open SpdySessions.
49*6777b538SAndroid Build Coastguard Worker class NET_EXPORT SpdySessionPool
50*6777b538SAndroid Build Coastguard Worker     : public NetworkChangeNotifier::IPAddressObserver,
51*6777b538SAndroid Build Coastguard Worker       public SSLClientContext::Observer {
52*6777b538SAndroid Build Coastguard Worker  public:
53*6777b538SAndroid Build Coastguard Worker   typedef base::TimeTicks (*TimeFunc)();
54*6777b538SAndroid Build Coastguard Worker 
55*6777b538SAndroid Build Coastguard Worker   // Struct to hold randomly generated frame parameters to be used for sending
56*6777b538SAndroid Build Coastguard Worker   // frames on the wire to "grease" frame type.  Frame type has to be one of
57*6777b538SAndroid Build Coastguard Worker   // the reserved values defined in
58*6777b538SAndroid Build Coastguard Worker   // https://tools.ietf.org/html/draft-bishop-httpbis-grease-00.
59*6777b538SAndroid Build Coastguard Worker   struct GreasedHttp2Frame {
60*6777b538SAndroid Build Coastguard Worker     uint8_t type;
61*6777b538SAndroid Build Coastguard Worker     uint8_t flags;
62*6777b538SAndroid Build Coastguard Worker     std::string payload;
63*6777b538SAndroid Build Coastguard Worker   };
64*6777b538SAndroid Build Coastguard Worker 
65*6777b538SAndroid Build Coastguard Worker   // A request for a SpdySession with a particular SpdySessionKey. The
66*6777b538SAndroid Build Coastguard Worker   // SpdySessionPool's RequestSession() creates these. The Delegate's
67*6777b538SAndroid Build Coastguard Worker   // OnSpdySessionAvailable() method will be invoked when a matching SpdySession
68*6777b538SAndroid Build Coastguard Worker   // is added to the pool. The Delegate's OnSpdySessionAvailable() method will
69*6777b538SAndroid Build Coastguard Worker   // be invoked at most once for a single SpdySessionRequest.
70*6777b538SAndroid Build Coastguard Worker   //
71*6777b538SAndroid Build Coastguard Worker   // Destroying the request will stop watching the pool for such a session. The
72*6777b538SAndroid Build Coastguard Worker   // request must be destroyed before the SpdySessionPool is.
73*6777b538SAndroid Build Coastguard Worker   class NET_EXPORT_PRIVATE SpdySessionRequest {
74*6777b538SAndroid Build Coastguard Worker    public:
75*6777b538SAndroid Build Coastguard Worker     // Interface for watching for when a SpdySession with a provided key is
76*6777b538SAndroid Build Coastguard Worker     // created.
77*6777b538SAndroid Build Coastguard Worker     class NET_EXPORT_PRIVATE Delegate {
78*6777b538SAndroid Build Coastguard Worker      public:
79*6777b538SAndroid Build Coastguard Worker       Delegate();
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker       Delegate(const Delegate&) = delete;
82*6777b538SAndroid Build Coastguard Worker       Delegate& operator=(const Delegate&) = delete;
83*6777b538SAndroid Build Coastguard Worker 
84*6777b538SAndroid Build Coastguard Worker       virtual ~Delegate();
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker       // |spdy_session| will not be null.
87*6777b538SAndroid Build Coastguard Worker       virtual void OnSpdySessionAvailable(
88*6777b538SAndroid Build Coastguard Worker           base::WeakPtr<SpdySession> spdy_session) = 0;
89*6777b538SAndroid Build Coastguard Worker     };
90*6777b538SAndroid Build Coastguard Worker 
91*6777b538SAndroid Build Coastguard Worker     // Constructor - this is called by the SpdySessionPool.
92*6777b538SAndroid Build Coastguard Worker     SpdySessionRequest(const SpdySessionKey& key,
93*6777b538SAndroid Build Coastguard Worker                        bool enable_ip_based_pooling,
94*6777b538SAndroid Build Coastguard Worker                        bool is_websocket,
95*6777b538SAndroid Build Coastguard Worker                        bool is_blocking_request_for_session,
96*6777b538SAndroid Build Coastguard Worker                        Delegate* delegate,
97*6777b538SAndroid Build Coastguard Worker                        SpdySessionPool* spdy_session_pool);
98*6777b538SAndroid Build Coastguard Worker 
99*6777b538SAndroid Build Coastguard Worker     SpdySessionRequest(const SpdySessionRequest&) = delete;
100*6777b538SAndroid Build Coastguard Worker     SpdySessionRequest& operator=(const SpdySessionRequest&) = delete;
101*6777b538SAndroid Build Coastguard Worker 
102*6777b538SAndroid Build Coastguard Worker     ~SpdySessionRequest();
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker     // Called by SpdySessionPool to signal that the request has been removed
105*6777b538SAndroid Build Coastguard Worker     // from the SpdySessionPool.
106*6777b538SAndroid Build Coastguard Worker     void OnRemovedFromPool();
107*6777b538SAndroid Build Coastguard Worker 
key()108*6777b538SAndroid Build Coastguard Worker     const SpdySessionKey& key() const { return key_; }
enable_ip_based_pooling()109*6777b538SAndroid Build Coastguard Worker     bool enable_ip_based_pooling() const { return enable_ip_based_pooling_; }
is_websocket()110*6777b538SAndroid Build Coastguard Worker     bool is_websocket() const { return is_websocket_; }
is_blocking_request_for_session()111*6777b538SAndroid Build Coastguard Worker     bool is_blocking_request_for_session() const {
112*6777b538SAndroid Build Coastguard Worker       return is_blocking_request_for_session_;
113*6777b538SAndroid Build Coastguard Worker     }
delegate()114*6777b538SAndroid Build Coastguard Worker     Delegate* delegate() { return delegate_; }
115*6777b538SAndroid Build Coastguard Worker 
116*6777b538SAndroid Build Coastguard Worker     // The associated SpdySessionPool, or nullptr if OnRemovedFromPool() has
117*6777b538SAndroid Build Coastguard Worker     // been called.
spdy_session_pool()118*6777b538SAndroid Build Coastguard Worker     SpdySessionPool* spdy_session_pool() { return spdy_session_pool_; }
119*6777b538SAndroid Build Coastguard Worker 
120*6777b538SAndroid Build Coastguard Worker    private:
121*6777b538SAndroid Build Coastguard Worker     const SpdySessionKey key_;
122*6777b538SAndroid Build Coastguard Worker     const bool enable_ip_based_pooling_;
123*6777b538SAndroid Build Coastguard Worker     const bool is_websocket_;
124*6777b538SAndroid Build Coastguard Worker     const bool is_blocking_request_for_session_;
125*6777b538SAndroid Build Coastguard Worker     const raw_ptr<Delegate> delegate_;
126*6777b538SAndroid Build Coastguard Worker     raw_ptr<SpdySessionPool> spdy_session_pool_;
127*6777b538SAndroid Build Coastguard Worker   };
128*6777b538SAndroid Build Coastguard Worker 
129*6777b538SAndroid Build Coastguard Worker   SpdySessionPool(HostResolver* host_resolver,
130*6777b538SAndroid Build Coastguard Worker                   SSLClientContext* ssl_client_context,
131*6777b538SAndroid Build Coastguard Worker                   HttpServerProperties* http_server_properties,
132*6777b538SAndroid Build Coastguard Worker                   TransportSecurityState* transport_security_state,
133*6777b538SAndroid Build Coastguard Worker                   const quic::ParsedQuicVersionVector& quic_supported_versions,
134*6777b538SAndroid Build Coastguard Worker                   bool enable_ping_based_connection_checking,
135*6777b538SAndroid Build Coastguard Worker                   bool is_http_enabled,
136*6777b538SAndroid Build Coastguard Worker                   bool is_quic_enabled,
137*6777b538SAndroid Build Coastguard Worker                   size_t session_max_recv_window_size,
138*6777b538SAndroid Build Coastguard Worker                   int session_max_queued_capped_frames,
139*6777b538SAndroid Build Coastguard Worker                   const spdy::SettingsMap& initial_settings,
140*6777b538SAndroid Build Coastguard Worker                   bool enable_http2_settings_grease,
141*6777b538SAndroid Build Coastguard Worker                   const std::optional<GreasedHttp2Frame>& greased_http2_frame,
142*6777b538SAndroid Build Coastguard Worker                   bool http2_end_stream_with_data_frame,
143*6777b538SAndroid Build Coastguard Worker                   bool enable_priority_update,
144*6777b538SAndroid Build Coastguard Worker                   bool go_away_on_ip_change,
145*6777b538SAndroid Build Coastguard Worker                   SpdySessionPool::TimeFunc time_func,
146*6777b538SAndroid Build Coastguard Worker                   NetworkQualityEstimator* network_quality_estimator,
147*6777b538SAndroid Build Coastguard Worker                   bool cleanup_sessions_on_ip_address_changed);
148*6777b538SAndroid Build Coastguard Worker 
149*6777b538SAndroid Build Coastguard Worker   SpdySessionPool(const SpdySessionPool&) = delete;
150*6777b538SAndroid Build Coastguard Worker   SpdySessionPool& operator=(const SpdySessionPool&) = delete;
151*6777b538SAndroid Build Coastguard Worker 
152*6777b538SAndroid Build Coastguard Worker   ~SpdySessionPool() override;
153*6777b538SAndroid Build Coastguard Worker 
154*6777b538SAndroid Build Coastguard Worker   // In the functions below, a session is "available" if this pool has
155*6777b538SAndroid Build Coastguard Worker   // a reference to it and there is some SpdySessionKey for which
156*6777b538SAndroid Build Coastguard Worker   // FindAvailableSession() will return it. A session is "unavailable"
157*6777b538SAndroid Build Coastguard Worker   // if this pool has a reference to it but it won't be returned by
158*6777b538SAndroid Build Coastguard Worker   // FindAvailableSession() for any SpdySessionKey; for example, this
159*6777b538SAndroid Build Coastguard Worker   // can happen when a session receives a GOAWAY frame and is still
160*6777b538SAndroid Build Coastguard Worker   // processing existing streams.
161*6777b538SAndroid Build Coastguard Worker 
162*6777b538SAndroid Build Coastguard Worker   // Create a new SPDY session from an existing socket.  There must
163*6777b538SAndroid Build Coastguard Worker   // not already be a session for the given key.
164*6777b538SAndroid Build Coastguard Worker   //
165*6777b538SAndroid Build Coastguard Worker   // Returns OK on success and sets |*session| to point to the new SpdySession.
166*6777b538SAndroid Build Coastguard Worker   // Returns a net error code on failure, in which case the value of |*session|
167*6777b538SAndroid Build Coastguard Worker   // is undefined.
168*6777b538SAndroid Build Coastguard Worker   //
169*6777b538SAndroid Build Coastguard Worker   // Note that the SpdySession begins reading from |client_socket_handle| on a
170*6777b538SAndroid Build Coastguard Worker   // subsequent event loop iteration, so it may be closed immediately afterwards
171*6777b538SAndroid Build Coastguard Worker   // if the first read of |client_socket_handle| fails.
172*6777b538SAndroid Build Coastguard Worker   int CreateAvailableSessionFromSocketHandle(
173*6777b538SAndroid Build Coastguard Worker       const SpdySessionKey& key,
174*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<ClientSocketHandle> client_socket_handle,
175*6777b538SAndroid Build Coastguard Worker       const NetLogWithSource& net_log,
176*6777b538SAndroid Build Coastguard Worker       base::WeakPtr<SpdySession>* session);
177*6777b538SAndroid Build Coastguard Worker 
178*6777b538SAndroid Build Coastguard Worker   // Just like the above method, except it takes a SocketStream instead of a
179*6777b538SAndroid Build Coastguard Worker   // ClientSocketHandle, and separate connect timing information. When this
180*6777b538SAndroid Build Coastguard Worker   // constructor is used, there is no socket pool beneath the SpdySession.
181*6777b538SAndroid Build Coastguard Worker   // Instead, the session takes exclusive ownership of the underting socket, and
182*6777b538SAndroid Build Coastguard Worker   // destroying the session will directly destroy the socket, as opposed to
183*6777b538SAndroid Build Coastguard Worker   // disconnected it and then returning it to the socket pool. This is intended
184*6777b538SAndroid Build Coastguard Worker   // for use with H2 proxies, which are layered beneath the socket pools and
185*6777b538SAndroid Build Coastguard Worker   // can have sockets above them for tunnels, which are put in a socket pool.
186*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> CreateAvailableSessionFromSocket(
187*6777b538SAndroid Build Coastguard Worker       const SpdySessionKey& key,
188*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<StreamSocket> socket_stream,
189*6777b538SAndroid Build Coastguard Worker       const LoadTimingInfo::ConnectTiming& connect_timing,
190*6777b538SAndroid Build Coastguard Worker       const NetLogWithSource& net_log);
191*6777b538SAndroid Build Coastguard Worker 
192*6777b538SAndroid Build Coastguard Worker   // If there is an available session for |key|, return it.
193*6777b538SAndroid Build Coastguard Worker   // Otherwise if there is a session to pool to based on IP address:
194*6777b538SAndroid Build Coastguard Worker   //   * if |enable_ip_based_pooling == true|,
195*6777b538SAndroid Build Coastguard Worker   //     then mark it as available for |key| and return it;
196*6777b538SAndroid Build Coastguard Worker   //   * if |enable_ip_based_pooling == false|,
197*6777b538SAndroid Build Coastguard Worker   //     then remove it from the available sessions, and return nullptr.
198*6777b538SAndroid Build Coastguard Worker   // Otherwise return nullptr.
199*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> FindAvailableSession(
200*6777b538SAndroid Build Coastguard Worker       const SpdySessionKey& key,
201*6777b538SAndroid Build Coastguard Worker       bool enable_ip_based_pooling,
202*6777b538SAndroid Build Coastguard Worker       bool is_websocket,
203*6777b538SAndroid Build Coastguard Worker       const NetLogWithSource& net_log);
204*6777b538SAndroid Build Coastguard Worker 
205*6777b538SAndroid Build Coastguard Worker   // Returns true if there is an available session for |key|.
206*6777b538SAndroid Build Coastguard Worker   bool HasAvailableSession(const SpdySessionKey& key, bool is_websocket) const;
207*6777b538SAndroid Build Coastguard Worker 
208*6777b538SAndroid Build Coastguard Worker   // Just like FindAvailableSession.
209*6777b538SAndroid Build Coastguard Worker   //
210*6777b538SAndroid Build Coastguard Worker   // Additionally, if it returns nullptr, populates |spdy_session_request| with
211*6777b538SAndroid Build Coastguard Worker   // a request that will invoke |delegate| once a matching SPDY session becomes
212*6777b538SAndroid Build Coastguard Worker   // available through the creation of a new SpdySession (as opposed to by
213*6777b538SAndroid Build Coastguard Worker   // creating an alias for an existing session with a new host).
214*6777b538SAndroid Build Coastguard Worker   //
215*6777b538SAndroid Build Coastguard Worker   // |is_blocking_request_for_session| will be set to |true| if there is not
216*6777b538SAndroid Build Coastguard Worker   // another "blocking" request already pending. For example, the first request
217*6777b538SAndroid Build Coastguard Worker   // created will be considered "blocking", but subsequent requests will not as
218*6777b538SAndroid Build Coastguard Worker   // long as the "blocking" request is not destroyed.  Once the "blocking"
219*6777b538SAndroid Build Coastguard Worker   // request is destroyed, the next created request will be marked "blocking".
220*6777b538SAndroid Build Coastguard Worker   //
221*6777b538SAndroid Build Coastguard Worker   // If a request is created, that request is not the "blocking" request, and
222*6777b538SAndroid Build Coastguard Worker   // |on_blocking_request_destroyed_callback| is non-null, then
223*6777b538SAndroid Build Coastguard Worker   // |on_blocking_request_destroyed_callback| will be invoked asynchronously
224*6777b538SAndroid Build Coastguard Worker   // when the "blocking" request is destroyed. The callback associated with the
225*6777b538SAndroid Build Coastguard Worker   // "blocking" request is never invoked.
226*6777b538SAndroid Build Coastguard Worker   //
227*6777b538SAndroid Build Coastguard Worker   // |delegate|, |spdy_session_request|, and |is_blocking_request_for_session|
228*6777b538SAndroid Build Coastguard Worker   // must all be non-null.
229*6777b538SAndroid Build Coastguard Worker   //
230*6777b538SAndroid Build Coastguard Worker   // TODO(mmenke): Merge this into FindAvailableSession().
231*6777b538SAndroid Build Coastguard Worker   // TODO(mmenke): Don't invoke |on_blocking_request_destroyed_callback| when
232*6777b538SAndroid Build Coastguard Worker   // all requests for a session have been successfully responded to.
233*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> RequestSession(
234*6777b538SAndroid Build Coastguard Worker       const SpdySessionKey& key,
235*6777b538SAndroid Build Coastguard Worker       bool enable_ip_based_pooling,
236*6777b538SAndroid Build Coastguard Worker       bool is_websocket,
237*6777b538SAndroid Build Coastguard Worker       const NetLogWithSource& net_log,
238*6777b538SAndroid Build Coastguard Worker       base::RepeatingClosure on_blocking_request_destroyed_callback,
239*6777b538SAndroid Build Coastguard Worker       SpdySessionRequest::Delegate* delegate,
240*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<SpdySessionRequest>* spdy_session_request,
241*6777b538SAndroid Build Coastguard Worker       bool* is_blocking_request_for_session);
242*6777b538SAndroid Build Coastguard Worker 
243*6777b538SAndroid Build Coastguard Worker   // Invoked when a host resolution completes. Returns
244*6777b538SAndroid Build Coastguard Worker   // OnHostResolutionCallbackResult::kMayBeDeletedAsync if there's a SPDY
245*6777b538SAndroid Build Coastguard Worker   // session that's a suitable alias for |key|, setting up the alias if needed.
246*6777b538SAndroid Build Coastguard Worker   OnHostResolutionCallbackResult OnHostResolutionComplete(
247*6777b538SAndroid Build Coastguard Worker       const SpdySessionKey& key,
248*6777b538SAndroid Build Coastguard Worker       bool is_websocket,
249*6777b538SAndroid Build Coastguard Worker       const std::vector<HostResolverEndpointResult>& endpoint_results,
250*6777b538SAndroid Build Coastguard Worker       const std::set<std::string>& aliases);
251*6777b538SAndroid Build Coastguard Worker 
252*6777b538SAndroid Build Coastguard Worker   // Remove all mappings and aliases for the given session, which must
253*6777b538SAndroid Build Coastguard Worker   // still be available. Except for in tests, this must be called by
254*6777b538SAndroid Build Coastguard Worker   // the given session itself.
255*6777b538SAndroid Build Coastguard Worker   void MakeSessionUnavailable(
256*6777b538SAndroid Build Coastguard Worker       const base::WeakPtr<SpdySession>& available_session);
257*6777b538SAndroid Build Coastguard Worker 
258*6777b538SAndroid Build Coastguard Worker   // Removes an unavailable session from the pool.  Except for in
259*6777b538SAndroid Build Coastguard Worker   // tests, this must be called by the given session itself.
260*6777b538SAndroid Build Coastguard Worker   void RemoveUnavailableSession(
261*6777b538SAndroid Build Coastguard Worker       const base::WeakPtr<SpdySession>& unavailable_session);
262*6777b538SAndroid Build Coastguard Worker 
263*6777b538SAndroid Build Coastguard Worker   // Note that the next three methods close sessions, potentially notifing
264*6777b538SAndroid Build Coastguard Worker   // delegates of error or synchronously invoking callbacks, which might trigger
265*6777b538SAndroid Build Coastguard Worker   // retries, thus opening new sessions.
266*6777b538SAndroid Build Coastguard Worker 
267*6777b538SAndroid Build Coastguard Worker   // Close only the currently existing SpdySessions with |error|.
268*6777b538SAndroid Build Coastguard Worker   // Let any new ones created while this method is running continue to
269*6777b538SAndroid Build Coastguard Worker   // live.
270*6777b538SAndroid Build Coastguard Worker   void CloseCurrentSessions(Error error);
271*6777b538SAndroid Build Coastguard Worker 
272*6777b538SAndroid Build Coastguard Worker   // Close only the currently existing SpdySessions that are idle.
273*6777b538SAndroid Build Coastguard Worker   // Let any new ones created while this method is running continue to
274*6777b538SAndroid Build Coastguard Worker   // live.
275*6777b538SAndroid Build Coastguard Worker   void CloseCurrentIdleSessions(const std::string& description);
276*6777b538SAndroid Build Coastguard Worker 
277*6777b538SAndroid Build Coastguard Worker   // Repeatedly close all SpdySessions until all of them (including new ones
278*6777b538SAndroid Build Coastguard Worker   // created in the process of closing the current ones, and new ones created in
279*6777b538SAndroid Build Coastguard Worker   // the process of closing those new ones, etc.) are unavailable.
280*6777b538SAndroid Build Coastguard Worker   void CloseAllSessions();
281*6777b538SAndroid Build Coastguard Worker 
282*6777b538SAndroid Build Coastguard Worker   // Mark all current sessions as going away.
283*6777b538SAndroid Build Coastguard Worker   void MakeCurrentSessionsGoingAway(Error error);
284*6777b538SAndroid Build Coastguard Worker 
285*6777b538SAndroid Build Coastguard Worker   // Creates a Value summary of the state of the spdy session pool.
286*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<base::Value> SpdySessionPoolInfoToValue() const;
287*6777b538SAndroid Build Coastguard Worker 
http_server_properties()288*6777b538SAndroid Build Coastguard Worker   HttpServerProperties* http_server_properties() {
289*6777b538SAndroid Build Coastguard Worker     return http_server_properties_;
290*6777b538SAndroid Build Coastguard Worker   }
291*6777b538SAndroid Build Coastguard Worker 
292*6777b538SAndroid Build Coastguard Worker   // NetworkChangeNotifier::IPAddressObserver methods:
293*6777b538SAndroid Build Coastguard Worker 
294*6777b538SAndroid Build Coastguard Worker   // We flush all idle sessions and release references to the active ones so
295*6777b538SAndroid Build Coastguard Worker   // they won't get re-used.  The active ones will either complete successfully
296*6777b538SAndroid Build Coastguard Worker   // or error out due to the IP address change.
297*6777b538SAndroid Build Coastguard Worker   void OnIPAddressChanged() override;
298*6777b538SAndroid Build Coastguard Worker 
299*6777b538SAndroid Build Coastguard Worker   // SSLClientContext::Observer methods:
300*6777b538SAndroid Build Coastguard Worker 
301*6777b538SAndroid Build Coastguard Worker   // We perform the same flushing as described above when SSL settings change.
302*6777b538SAndroid Build Coastguard Worker   void OnSSLConfigChanged(
303*6777b538SAndroid Build Coastguard Worker       SSLClientContext::SSLConfigChangeType change_type) override;
304*6777b538SAndroid Build Coastguard Worker 
305*6777b538SAndroid Build Coastguard Worker   // Makes all sessions using |server|'s SSL configuration unavailable, meaning
306*6777b538SAndroid Build Coastguard Worker   // they will not be used to service new streams. Does not close any existing
307*6777b538SAndroid Build Coastguard Worker   // streams.
308*6777b538SAndroid Build Coastguard Worker   void OnSSLConfigForServersChanged(
309*6777b538SAndroid Build Coastguard Worker       const base::flat_set<HostPortPair>& servers) override;
310*6777b538SAndroid Build Coastguard Worker 
set_network_quality_estimator(NetworkQualityEstimator * network_quality_estimator)311*6777b538SAndroid Build Coastguard Worker   void set_network_quality_estimator(
312*6777b538SAndroid Build Coastguard Worker       NetworkQualityEstimator* network_quality_estimator) {
313*6777b538SAndroid Build Coastguard Worker     network_quality_estimator_ = network_quality_estimator;
314*6777b538SAndroid Build Coastguard Worker   }
315*6777b538SAndroid Build Coastguard Worker 
316*6777b538SAndroid Build Coastguard Worker   // Returns the stored DNS aliases for the session key.
317*6777b538SAndroid Build Coastguard Worker   std::set<std::string> GetDnsAliasesForSessionKey(
318*6777b538SAndroid Build Coastguard Worker       const SpdySessionKey& key) const;
319*6777b538SAndroid Build Coastguard Worker 
320*6777b538SAndroid Build Coastguard Worker  private:
321*6777b538SAndroid Build Coastguard Worker   friend class SpdySessionPoolPeer;  // For testing.
322*6777b538SAndroid Build Coastguard Worker 
323*6777b538SAndroid Build Coastguard Worker   using SessionSet = std::set<raw_ptr<SpdySession, SetExperimental>>;
324*6777b538SAndroid Build Coastguard Worker   using WeakSessionList = std::vector<base::WeakPtr<SpdySession>>;
325*6777b538SAndroid Build Coastguard Worker   using AvailableSessionMap =
326*6777b538SAndroid Build Coastguard Worker       std::map<SpdySessionKey, base::WeakPtr<SpdySession>>;
327*6777b538SAndroid Build Coastguard Worker   using AliasMap = std::multimap<IPEndPoint, SpdySessionKey>;
328*6777b538SAndroid Build Coastguard Worker   using DnsAliasesBySessionKeyMap =
329*6777b538SAndroid Build Coastguard Worker       std::map<SpdySessionKey, std::set<std::string>>;
330*6777b538SAndroid Build Coastguard Worker   using RequestSet = std::set<raw_ptr<SpdySessionRequest, SetExperimental>>;
331*6777b538SAndroid Build Coastguard Worker 
332*6777b538SAndroid Build Coastguard Worker   struct RequestInfoForKey {
333*6777b538SAndroid Build Coastguard Worker     RequestInfoForKey();
334*6777b538SAndroid Build Coastguard Worker     ~RequestInfoForKey();
335*6777b538SAndroid Build Coastguard Worker 
336*6777b538SAndroid Build Coastguard Worker     // Whether one of the requests in |RequestSet| has its
337*6777b538SAndroid Build Coastguard Worker     // is_blocking_request_for_session() bit set.
338*6777b538SAndroid Build Coastguard Worker     bool has_blocking_request = false;
339*6777b538SAndroid Build Coastguard Worker 
340*6777b538SAndroid Build Coastguard Worker     RequestSet request_set;
341*6777b538SAndroid Build Coastguard Worker 
342*6777b538SAndroid Build Coastguard Worker     // Set of callbacks watching for the blocking request to be destroyed.
343*6777b538SAndroid Build Coastguard Worker     std::list<base::RepeatingClosure> deferred_callbacks;
344*6777b538SAndroid Build Coastguard Worker   };
345*6777b538SAndroid Build Coastguard Worker 
346*6777b538SAndroid Build Coastguard Worker   using SpdySessionRequestMap = std::map<SpdySessionKey, RequestInfoForKey>;
347*6777b538SAndroid Build Coastguard Worker 
348*6777b538SAndroid Build Coastguard Worker   // Removes |request| from |spdy_session_request_map_|.
349*6777b538SAndroid Build Coastguard Worker   void RemoveRequestForSpdySession(SpdySessionRequest* request);
350*6777b538SAndroid Build Coastguard Worker 
351*6777b538SAndroid Build Coastguard Worker   // Returns true iff |session| is in |available_sessions_|.
352*6777b538SAndroid Build Coastguard Worker   bool IsSessionAvailable(const base::WeakPtr<SpdySession>& session) const;
353*6777b538SAndroid Build Coastguard Worker 
354*6777b538SAndroid Build Coastguard Worker   // Map the given key to the given session. There must not already be a
355*6777b538SAndroid Build Coastguard Worker   // mapping for `key`. Also adds an entry for `key` and `dns_aliases` in
356*6777b538SAndroid Build Coastguard Worker   // `dns_aliases_by_session_key_`. If there are already DNS aliases for the
357*6777b538SAndroid Build Coastguard Worker   // given key, replaces them.
358*6777b538SAndroid Build Coastguard Worker   void MapKeyToAvailableSession(const SpdySessionKey& key,
359*6777b538SAndroid Build Coastguard Worker                                 const base::WeakPtr<SpdySession>& session,
360*6777b538SAndroid Build Coastguard Worker                                 std::set<std::string> dns_aliases);
361*6777b538SAndroid Build Coastguard Worker 
362*6777b538SAndroid Build Coastguard Worker   // Returns an iterator into |available_sessions_| for the given key,
363*6777b538SAndroid Build Coastguard Worker   // which may be equal to |available_sessions_.end()|.
364*6777b538SAndroid Build Coastguard Worker   AvailableSessionMap::iterator LookupAvailableSessionByKey(
365*6777b538SAndroid Build Coastguard Worker       const SpdySessionKey& key);
366*6777b538SAndroid Build Coastguard Worker 
367*6777b538SAndroid Build Coastguard Worker   // Remove the mapping of the given key, which must exist. Also erases the
368*6777b538SAndroid Build Coastguard Worker   // key-value pair of SpdySessionKey and DNS aliases from the
369*6777b538SAndroid Build Coastguard Worker   // `dns_aliases_by_session_key_` map.
370*6777b538SAndroid Build Coastguard Worker   void UnmapKey(const SpdySessionKey& key);
371*6777b538SAndroid Build Coastguard Worker 
372*6777b538SAndroid Build Coastguard Worker   // Remove all aliases for |key| from the aliases table.
373*6777b538SAndroid Build Coastguard Worker   void RemoveAliases(const SpdySessionKey& key);
374*6777b538SAndroid Build Coastguard Worker 
375*6777b538SAndroid Build Coastguard Worker   // Get a copy of the current sessions as a list of WeakPtrs. Used by
376*6777b538SAndroid Build Coastguard Worker   // CloseCurrentSessionsHelper() below.
377*6777b538SAndroid Build Coastguard Worker   WeakSessionList GetCurrentSessions() const;
378*6777b538SAndroid Build Coastguard Worker 
379*6777b538SAndroid Build Coastguard Worker   // Close only the currently existing SpdySessions with |error|.  Let
380*6777b538SAndroid Build Coastguard Worker   // any new ones created while this method is running continue to
381*6777b538SAndroid Build Coastguard Worker   // live. If |idle_only| is true only idle sessions are closed.
382*6777b538SAndroid Build Coastguard Worker   void CloseCurrentSessionsHelper(Error error,
383*6777b538SAndroid Build Coastguard Worker                                   const std::string& description,
384*6777b538SAndroid Build Coastguard Worker                                   bool idle_only);
385*6777b538SAndroid Build Coastguard Worker 
386*6777b538SAndroid Build Coastguard Worker   // Creates a new session. The session must be initialized before
387*6777b538SAndroid Build Coastguard Worker   // InsertSession() is invoked.
388*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<SpdySession> CreateSession(const SpdySessionKey& key,
389*6777b538SAndroid Build Coastguard Worker                                              NetLog* net_log);
390*6777b538SAndroid Build Coastguard Worker   // Adds a new session previously created with CreateSession to the pool.
391*6777b538SAndroid Build Coastguard Worker   // |source_net_log| is the NetLog for the object that created the session.
392*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdySession> InsertSession(
393*6777b538SAndroid Build Coastguard Worker       const SpdySessionKey& key,
394*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<SpdySession> new_session,
395*6777b538SAndroid Build Coastguard Worker       const NetLogWithSource& source_net_log,
396*6777b538SAndroid Build Coastguard Worker       std::set<std::string> dns_aliases);
397*6777b538SAndroid Build Coastguard Worker 
398*6777b538SAndroid Build Coastguard Worker   // If a session with the specified |key| exists, invokes
399*6777b538SAndroid Build Coastguard Worker   // OnSpdySessionAvailable on all matching members of
400*6777b538SAndroid Build Coastguard Worker   // |spdy_session_request_map_|, removing them from the map. Regardless of
401*6777b538SAndroid Build Coastguard Worker   // whether or not such key exists, invokes all corresponding callbacks
402*6777b538SAndroid Build Coastguard Worker   // currently in |spdy_session_pending_request_map_|.
403*6777b538SAndroid Build Coastguard Worker   void UpdatePendingRequests(const SpdySessionKey& key);
404*6777b538SAndroid Build Coastguard Worker 
405*6777b538SAndroid Build Coastguard Worker   // Removes the SpdySessionRequest at |request_set_iterator| from the
406*6777b538SAndroid Build Coastguard Worker   // RequestSet at |request_map_iterator| and calls OnRemovedFromPool() on the
407*6777b538SAndroid Build Coastguard Worker   // request. If the RequestSet becomes empty, also removes it from
408*6777b538SAndroid Build Coastguard Worker   // |spdy_session_request_map_|.
409*6777b538SAndroid Build Coastguard Worker   void RemoveRequestInternal(
410*6777b538SAndroid Build Coastguard Worker       SpdySessionRequestMap::iterator request_map_iterator,
411*6777b538SAndroid Build Coastguard Worker       RequestSet::iterator request_set_iterator);
412*6777b538SAndroid Build Coastguard Worker 
413*6777b538SAndroid Build Coastguard Worker   raw_ptr<HttpServerProperties> http_server_properties_;
414*6777b538SAndroid Build Coastguard Worker 
415*6777b538SAndroid Build Coastguard Worker   raw_ptr<TransportSecurityState> transport_security_state_;
416*6777b538SAndroid Build Coastguard Worker 
417*6777b538SAndroid Build Coastguard Worker   // The set of all sessions. This is a superset of the sessions in
418*6777b538SAndroid Build Coastguard Worker   // |available_sessions_|.
419*6777b538SAndroid Build Coastguard Worker   //
420*6777b538SAndroid Build Coastguard Worker   // |sessions_| owns all its SpdySession objects.
421*6777b538SAndroid Build Coastguard Worker   SessionSet sessions_;
422*6777b538SAndroid Build Coastguard Worker 
423*6777b538SAndroid Build Coastguard Worker   // This is a map of available sessions by key. A session may appear
424*6777b538SAndroid Build Coastguard Worker   // more than once in this map if it has aliases.
425*6777b538SAndroid Build Coastguard Worker   AvailableSessionMap available_sessions_;
426*6777b538SAndroid Build Coastguard Worker 
427*6777b538SAndroid Build Coastguard Worker   // A map of IPEndPoint aliases for sessions.
428*6777b538SAndroid Build Coastguard Worker   AliasMap aliases_;
429*6777b538SAndroid Build Coastguard Worker 
430*6777b538SAndroid Build Coastguard Worker   // A map of DNS alias vectors by session keys.
431*6777b538SAndroid Build Coastguard Worker   DnsAliasesBySessionKeyMap dns_aliases_by_session_key_;
432*6777b538SAndroid Build Coastguard Worker 
433*6777b538SAndroid Build Coastguard Worker   const raw_ptr<SSLClientContext> ssl_client_context_;
434*6777b538SAndroid Build Coastguard Worker   const raw_ptr<HostResolver> resolver_;
435*6777b538SAndroid Build Coastguard Worker 
436*6777b538SAndroid Build Coastguard Worker   // Versions of QUIC which may be used.
437*6777b538SAndroid Build Coastguard Worker   const quic::ParsedQuicVersionVector quic_supported_versions_;
438*6777b538SAndroid Build Coastguard Worker 
439*6777b538SAndroid Build Coastguard Worker   // Defaults to true. May be controlled via SpdySessionPoolPeer for tests.
440*6777b538SAndroid Build Coastguard Worker   bool enable_sending_initial_data_ = true;
441*6777b538SAndroid Build Coastguard Worker   bool enable_ping_based_connection_checking_;
442*6777b538SAndroid Build Coastguard Worker 
443*6777b538SAndroid Build Coastguard Worker   const bool is_http2_enabled_;
444*6777b538SAndroid Build Coastguard Worker   const bool is_quic_enabled_;
445*6777b538SAndroid Build Coastguard Worker 
446*6777b538SAndroid Build Coastguard Worker   size_t session_max_recv_window_size_;
447*6777b538SAndroid Build Coastguard Worker 
448*6777b538SAndroid Build Coastguard Worker   // Maximum number of capped frames that can be queued at any time.
449*6777b538SAndroid Build Coastguard Worker   int session_max_queued_capped_frames_;
450*6777b538SAndroid Build Coastguard Worker 
451*6777b538SAndroid Build Coastguard Worker   // Settings that are sent in the initial SETTINGS frame
452*6777b538SAndroid Build Coastguard Worker   // (if |enable_sending_initial_data_| is true),
453*6777b538SAndroid Build Coastguard Worker   // and also control SpdySession parameters like initial receive window size
454*6777b538SAndroid Build Coastguard Worker   // and maximum HPACK dynamic table size.
455*6777b538SAndroid Build Coastguard Worker   const spdy::SettingsMap initial_settings_;
456*6777b538SAndroid Build Coastguard Worker 
457*6777b538SAndroid Build Coastguard Worker   // If true, a setting parameter with reserved identifier will be sent in every
458*6777b538SAndroid Build Coastguard Worker   // initial SETTINGS frame, see
459*6777b538SAndroid Build Coastguard Worker   // https://tools.ietf.org/html/draft-bishop-httpbis-grease-00.
460*6777b538SAndroid Build Coastguard Worker   // The setting identifier and value will be drawn independently for each
461*6777b538SAndroid Build Coastguard Worker   // connection to prevent tracking of the client.
462*6777b538SAndroid Build Coastguard Worker   const bool enable_http2_settings_grease_;
463*6777b538SAndroid Build Coastguard Worker 
464*6777b538SAndroid Build Coastguard Worker   // If set, an HTTP/2 frame with a reserved frame type will be sent after
465*6777b538SAndroid Build Coastguard Worker   // every HTTP/2 SETTINGS frame and before every HTTP/2 DATA frame. See
466*6777b538SAndroid Build Coastguard Worker   // https://tools.ietf.org/html/draft-bishop-httpbis-grease-00.
467*6777b538SAndroid Build Coastguard Worker   const std::optional<GreasedHttp2Frame> greased_http2_frame_;
468*6777b538SAndroid Build Coastguard Worker 
469*6777b538SAndroid Build Coastguard Worker   // If set, the HEADERS frame carrying a request without body will not have the
470*6777b538SAndroid Build Coastguard Worker   // END_STREAM flag set.  The stream will be closed by a subsequent empty DATA
471*6777b538SAndroid Build Coastguard Worker   // frame with END_STREAM.  Does not affect bidirectional or proxy streams.
472*6777b538SAndroid Build Coastguard Worker   // If unset, the HEADERS frame will have the END_STREAM flag set on.
473*6777b538SAndroid Build Coastguard Worker   // This is useful in conjuction with |greased_http2_frame_| so that a frame
474*6777b538SAndroid Build Coastguard Worker   // of reserved type can be sent out even on requests without a body.
475*6777b538SAndroid Build Coastguard Worker   const bool http2_end_stream_with_data_frame_;
476*6777b538SAndroid Build Coastguard Worker 
477*6777b538SAndroid Build Coastguard Worker   // If true, enable sending PRIORITY_UPDATE frames until SETTINGS frame
478*6777b538SAndroid Build Coastguard Worker   // arrives.  After SETTINGS frame arrives, do not send PRIORITY_UPDATE frames
479*6777b538SAndroid Build Coastguard Worker   // any longer if SETTINGS_DEPRECATE_HTTP2_PRIORITIES is missing or has zero 0,
480*6777b538SAndroid Build Coastguard Worker   // but continue and also stop sending HTTP/2-style priority information in
481*6777b538SAndroid Build Coastguard Worker   // HEADERS frames and PRIORITY frames if it has value 1.
482*6777b538SAndroid Build Coastguard Worker   const bool enable_priority_update_;
483*6777b538SAndroid Build Coastguard Worker 
484*6777b538SAndroid Build Coastguard Worker   // If set, sessions will be marked as going away upon relevant network changes
485*6777b538SAndroid Build Coastguard Worker   // (instead of being closed).
486*6777b538SAndroid Build Coastguard Worker   const bool go_away_on_ip_change_;
487*6777b538SAndroid Build Coastguard Worker 
488*6777b538SAndroid Build Coastguard Worker   SpdySessionRequestMap spdy_session_request_map_;
489*6777b538SAndroid Build Coastguard Worker 
490*6777b538SAndroid Build Coastguard Worker   TimeFunc time_func_;
491*6777b538SAndroid Build Coastguard Worker 
492*6777b538SAndroid Build Coastguard Worker   raw_ptr<NetworkQualityEstimator> network_quality_estimator_;
493*6777b538SAndroid Build Coastguard Worker 
494*6777b538SAndroid Build Coastguard Worker   const bool cleanup_sessions_on_ip_address_changed_;
495*6777b538SAndroid Build Coastguard Worker 
496*6777b538SAndroid Build Coastguard Worker   base::WeakPtrFactory<SpdySessionPool> weak_ptr_factory_{this};
497*6777b538SAndroid Build Coastguard Worker };
498*6777b538SAndroid Build Coastguard Worker 
499*6777b538SAndroid Build Coastguard Worker }  // namespace net
500*6777b538SAndroid Build Coastguard Worker 
501*6777b538SAndroid Build Coastguard Worker #endif  // NET_SPDY_SPDY_SESSION_POOL_H_
502