| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 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_SPDY_SPDY_SESSION_POOL_H_ | |
| 6 #define NET_SPDY_SPDY_SESSION_POOL_H_ | |
| 7 | |
| 8 #include <stddef.h> | |
| 9 | |
| 10 #include <map> | |
| 11 #include <memory> | |
| 12 #include <set> | |
| 13 #include <vector> | |
| 14 | |
| 15 #include "base/macros.h" | |
| 16 #include "base/memory/ref_counted.h" | |
| 17 #include "base/memory/weak_ptr.h" | |
| 18 #include "net/base/host_port_pair.h" | |
| 19 #include "net/base/ip_endpoint.h" | |
| 20 #include "net/base/net_errors.h" | |
| 21 #include "net/base/net_export.h" | |
| 22 #include "net/base/network_change_notifier.h" | |
| 23 #include "net/cert/cert_database.h" | |
| 24 #include "net/proxy/proxy_config.h" | |
| 25 #include "net/proxy/proxy_server.h" | |
| 26 #include "net/spdy/platform/api/spdy_string.h" | |
| 27 #include "net/spdy/server_push_delegate.h" | |
| 28 #include "net/spdy/spdy_protocol.h" | |
| 29 #include "net/spdy/spdy_session_key.h" | |
| 30 #include "net/ssl/ssl_config_service.h" | |
| 31 | |
| 32 namespace base { | |
| 33 namespace trace_event { | |
| 34 class ProcessMemoryDump; | |
| 35 } | |
| 36 } | |
| 37 | |
| 38 namespace net { | |
| 39 | |
| 40 class ClientSocketHandle; | |
| 41 class HostResolver; | |
| 42 class HttpServerProperties; | |
| 43 class NetLogWithSource; | |
| 44 class ProxyDelegate; | |
| 45 class SpdySession; | |
| 46 class TransportSecurityState; | |
| 47 | |
| 48 // This is a very simple pool for open SpdySessions. | |
| 49 class NET_EXPORT SpdySessionPool | |
| 50 : public NetworkChangeNotifier::IPAddressObserver, | |
| 51 public SSLConfigService::Observer, | |
| 52 public CertDatabase::Observer { | |
| 53 public: | |
| 54 typedef base::TimeTicks (*TimeFunc)(void); | |
| 55 | |
| 56 SpdySessionPool(HostResolver* host_resolver, | |
| 57 SSLConfigService* ssl_config_service, | |
| 58 HttpServerProperties* http_server_properties, | |
| 59 TransportSecurityState* transport_security_state, | |
| 60 bool enable_ping_based_connection_checking, | |
| 61 size_t session_max_recv_window_size, | |
| 62 const SettingsMap& initial_settings, | |
| 63 SpdySessionPool::TimeFunc time_func, | |
| 64 ProxyDelegate* proxy_delegate); | |
| 65 ~SpdySessionPool() override; | |
| 66 | |
| 67 // In the functions below, a session is "available" if this pool has | |
| 68 // a reference to it and there is some SpdySessionKey for which | |
| 69 // FindAvailableSession() will return it. A session is "unavailable" | |
| 70 // if this pool has a reference to it but it won't be returned by | |
| 71 // FindAvailableSession() for any SpdySessionKey; for example, this | |
| 72 // can happen when a session receives a GOAWAY frame and is still | |
| 73 // processing existing streams. | |
| 74 | |
| 75 // Create a new SPDY session from an existing socket. There must | |
| 76 // not already be a session for the given key. | |
| 77 // | |
| 78 // |is_secure| can be false for testing or when SPDY is configured | |
| 79 // to work with non-secure sockets. | |
| 80 // | |
| 81 // Returns the new SpdySession. Note that the SpdySession begins reading from | |
| 82 // |connection| on a subsequent event loop iteration, so it may be closed | |
| 83 // immediately afterwards if the first read of |connection| fails. | |
| 84 base::WeakPtr<SpdySession> CreateAvailableSessionFromSocket( | |
| 85 const SpdySessionKey& key, | |
| 86 std::unique_ptr<ClientSocketHandle> connection, | |
| 87 const NetLogWithSource& net_log, | |
| 88 bool is_secure); | |
| 89 | |
| 90 // If |url| is not empty and there is a session for |key| that has an | |
| 91 // unclaimed push stream for |url|, return it. | |
| 92 // Otherwise if there is an available session for |key|, return it. | |
| 93 // Otherwise if there is a session to pool to based on IP address: | |
| 94 // * if |enable_ip_based_pooling == true|, | |
| 95 // then mark it as available for |key| and return it; | |
| 96 // * if |enable_ip_based_pooling == false|, | |
| 97 // then remove it from the available sessions, and return nullptr. | |
| 98 // Otherwise return nullptr. | |
| 99 base::WeakPtr<SpdySession> FindAvailableSession( | |
| 100 const SpdySessionKey& key, | |
| 101 const GURL& url, | |
| 102 bool enable_ip_based_pooling, | |
| 103 const NetLogWithSource& net_log); | |
| 104 | |
| 105 // Remove all mappings and aliases for the given session, which must | |
| 106 // still be available. Except for in tests, this must be called by | |
| 107 // the given session itself. | |
| 108 void MakeSessionUnavailable( | |
| 109 const base::WeakPtr<SpdySession>& available_session); | |
| 110 | |
| 111 // Removes an unavailable session from the pool. Except for in | |
| 112 // tests, this must be called by the given session itself. | |
| 113 void RemoveUnavailableSession( | |
| 114 const base::WeakPtr<SpdySession>& unavailable_session); | |
| 115 | |
| 116 // Close only the currently existing SpdySessions with |error|. | |
| 117 // Let any new ones created while this method is running continue to | |
| 118 // live. | |
| 119 void CloseCurrentSessions(Error error); | |
| 120 | |
| 121 // Close only the currently existing SpdySessions that are idle. | |
| 122 // Let any new ones created while this method is running continue to | |
| 123 // live. | |
| 124 void CloseCurrentIdleSessions(); | |
| 125 | |
| 126 // Close all SpdySessions, including any new ones created in the process of | |
| 127 // closing the current ones. | |
| 128 void CloseAllSessions(); | |
| 129 | |
| 130 // (Un)register a SpdySession with an unclaimed pushed stream for |url|, so | |
| 131 // that the right SpdySession can be served by FindAvailableSession. | |
| 132 void RegisterUnclaimedPushedStream(GURL url, | |
| 133 base::WeakPtr<SpdySession> spdy_session); | |
| 134 void UnregisterUnclaimedPushedStream(const GURL& url, | |
| 135 SpdySession* spdy_session); | |
| 136 | |
| 137 // Creates a Value summary of the state of the spdy session pool. | |
| 138 std::unique_ptr<base::Value> SpdySessionPoolInfoToValue() const; | |
| 139 | |
| 140 HttpServerProperties* http_server_properties() { | |
| 141 return http_server_properties_; | |
| 142 } | |
| 143 | |
| 144 void set_server_push_delegate(ServerPushDelegate* push_delegate) { | |
| 145 push_delegate_ = push_delegate; | |
| 146 } | |
| 147 | |
| 148 // NetworkChangeNotifier::IPAddressObserver methods: | |
| 149 | |
| 150 // We flush all idle sessions and release references to the active ones so | |
| 151 // they won't get re-used. The active ones will either complete successfully | |
| 152 // or error out due to the IP address change. | |
| 153 void OnIPAddressChanged() override; | |
| 154 | |
| 155 // SSLConfigService::Observer methods: | |
| 156 | |
| 157 // We perform the same flushing as described above when SSL settings change. | |
| 158 void OnSSLConfigChanged() override; | |
| 159 | |
| 160 // CertDatabase::Observer methods: | |
| 161 | |
| 162 // We perform the same flushing as described above when certificate database | |
| 163 // is changed. | |
| 164 void OnCertDBChanged() override; | |
| 165 | |
| 166 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd, | |
| 167 const SpdyString& parent_dump_absolute_name) const; | |
| 168 | |
| 169 private: | |
| 170 friend class SpdySessionPoolPeer; // For testing. | |
| 171 | |
| 172 typedef std::set<SpdySession*> SessionSet; | |
| 173 typedef std::vector<base::WeakPtr<SpdySession> > WeakSessionList; | |
| 174 typedef std::map<SpdySessionKey, base::WeakPtr<SpdySession> > | |
| 175 AvailableSessionMap; | |
| 176 typedef std::map<IPEndPoint, SpdySessionKey> AliasMap; | |
| 177 typedef std::map<GURL, WeakSessionList> UnclaimedPushedStreamMap; | |
| 178 | |
| 179 // Returns true iff |session| is in |available_sessions_|. | |
| 180 bool IsSessionAvailable(const base::WeakPtr<SpdySession>& session) const; | |
| 181 | |
| 182 // Map the given key to the given session. There must not already be | |
| 183 // a mapping for |key|. | |
| 184 void MapKeyToAvailableSession(const SpdySessionKey& key, | |
| 185 const base::WeakPtr<SpdySession>& session); | |
| 186 | |
| 187 // Returns an iterator into |available_sessions_| for the given key, | |
| 188 // which may be equal to |available_sessions_.end()|. | |
| 189 AvailableSessionMap::iterator LookupAvailableSessionByKey( | |
| 190 const SpdySessionKey& key); | |
| 191 | |
| 192 // Remove the mapping of the given key, which must exist. | |
| 193 void UnmapKey(const SpdySessionKey& key); | |
| 194 | |
| 195 // Remove all aliases for |key| from the aliases table. | |
| 196 void RemoveAliases(const SpdySessionKey& key); | |
| 197 | |
| 198 // Get a copy of the current sessions as a list of WeakPtrs. Used by | |
| 199 // CloseCurrentSessionsHelper() below. | |
| 200 WeakSessionList GetCurrentSessions() const; | |
| 201 | |
| 202 // Close only the currently existing SpdySessions with |error|. Let | |
| 203 // any new ones created while this method is running continue to | |
| 204 // live. If |idle_only| is true only idle sessions are closed. | |
| 205 void CloseCurrentSessionsHelper(Error error, | |
| 206 const SpdyString& description, | |
| 207 bool idle_only); | |
| 208 | |
| 209 HttpServerProperties* http_server_properties_; | |
| 210 | |
| 211 TransportSecurityState* transport_security_state_; | |
| 212 | |
| 213 // The set of all sessions. This is a superset of the sessions in | |
| 214 // |available_sessions_|. | |
| 215 // | |
| 216 // |sessions_| owns all its SpdySession objects. | |
| 217 SessionSet sessions_; | |
| 218 | |
| 219 // This is a map of available sessions by key. A session may appear | |
| 220 // more than once in this map if it has aliases. | |
| 221 AvailableSessionMap available_sessions_; | |
| 222 | |
| 223 // A map of IPEndPoint aliases for sessions. | |
| 224 AliasMap aliases_; | |
| 225 | |
| 226 // A map of all SpdySessions owned by |this| that have an unclaimed pushed | |
| 227 // streams for a GURL. Might contain invalid WeakPtr's. | |
| 228 // A single SpdySession can only have at most one pushed stream for each GURL, | |
| 229 // but it is possible that multiple SpdySessions have pushed streams for the | |
| 230 // same GURL. | |
| 231 UnclaimedPushedStreamMap unclaimed_pushed_streams_; | |
| 232 | |
| 233 const scoped_refptr<SSLConfigService> ssl_config_service_; | |
| 234 HostResolver* const resolver_; | |
| 235 | |
| 236 // Defaults to true. May be controlled via SpdySessionPoolPeer for tests. | |
| 237 bool enable_sending_initial_data_; | |
| 238 bool enable_ping_based_connection_checking_; | |
| 239 | |
| 240 size_t session_max_recv_window_size_; | |
| 241 | |
| 242 // Settings that are sent in the initial SETTINGS frame | |
| 243 // (if |enable_sending_initial_data_| is true), | |
| 244 // and also control SpdySession parameters like initial receive window size | |
| 245 // and maximum HPACK dynamic table size. | |
| 246 const SettingsMap initial_settings_; | |
| 247 | |
| 248 TimeFunc time_func_; | |
| 249 ServerPushDelegate* push_delegate_; | |
| 250 | |
| 251 // Determines if a proxy is a trusted SPDY proxy, which is allowed to push | |
| 252 // resources from origins that are different from those of their associated | |
| 253 // streams. May be nullptr. | |
| 254 ProxyDelegate* proxy_delegate_; | |
| 255 | |
| 256 DISALLOW_COPY_AND_ASSIGN(SpdySessionPool); | |
| 257 }; | |
| 258 | |
| 259 } // namespace net | |
| 260 | |
| 261 #endif // NET_SPDY_SPDY_SESSION_POOL_H_ | |
| OLD | NEW |