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