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 <map> 9 #include <set> 10 #include <string> 11 #include <vector> 12 13 #include "base/basictypes.h" 14 #include "base/gtest_prod_util.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/memory/weak_ptr.h" 17 #include "net/base/host_port_pair.h" 18 #include "net/base/ip_endpoint.h" 19 #include "net/base/net_errors.h" 20 #include "net/base/net_export.h" 21 #include "net/base/network_change_notifier.h" 22 #include "net/cert/cert_database.h" 23 #include "net/proxy/proxy_config.h" 24 #include "net/proxy/proxy_server.h" 25 #include "net/socket/next_proto.h" 26 #include "net/spdy/spdy_session_key.h" 27 #include "net/ssl/ssl_config_service.h" 28 29 namespace net { 30 31 class AddressList; 32 class BoundNetLog; 33 class ClientSocketHandle; 34 class HostResolver; 35 class HttpServerProperties; 36 class SpdySession; 37 38 // This is a very simple pool for open SpdySessions. 39 class NET_EXPORT SpdySessionPool 40 : public NetworkChangeNotifier::IPAddressObserver, 41 public SSLConfigService::Observer, 42 public CertDatabase::Observer { 43 public: 44 typedef base::TimeTicks (*TimeFunc)(void); 45 46 // |default_protocol| may be kProtoUnknown (e.g., if SPDY is 47 // disabled), in which case it's set to a default value. Otherwise, 48 // it must be a SPDY protocol. 49 SpdySessionPool( 50 HostResolver* host_resolver, 51 SSLConfigService* ssl_config_service, 52 const base::WeakPtr<HttpServerProperties>& http_server_properties, 53 bool force_single_domain, 54 bool enable_ip_pooling, 55 bool enable_compression, 56 bool enable_ping_based_connection_checking, 57 NextProto default_protocol, 58 size_t stream_initial_recv_window_size, 59 size_t initial_max_concurrent_streams, 60 size_t max_concurrent_streams_limit, 61 SpdySessionPool::TimeFunc time_func, 62 const std::string& trusted_spdy_proxy); 63 virtual ~SpdySessionPool(); 64 65 // In the functions below, a session is "available" if this pool has 66 // a reference to it and there is some SpdySessionKey for which 67 // FindAvailableSession() will return it. A session is "unavailable" 68 // if this pool has a reference to it but it won't be returned by 69 // FindAvailableSession() for any SpdySessionKey; for example, this 70 // can happen when a session receives a GOAWAY frame and is still 71 // processing existing streams. 72 73 // Create a new SPDY session from an existing socket. There must 74 // not already be a session for the given key. This pool must have 75 // been constructed with a valid |default_protocol| value. 76 // 77 // |is_secure| can be false for testing or when SPDY is configured 78 // to work with non-secure sockets. If |is_secure| is true, 79 // |certificate_error_code| indicates that the certificate error 80 // encountered when connecting the SSL socket, with OK meaning there 81 // was no error. 82 // 83 // If successful, OK is returned and |available_session| will be 84 // non-NULL and available. Otherwise, an error is returned and 85 // |available_session| will be NULL. 86 net::Error CreateAvailableSessionFromSocket( 87 const SpdySessionKey& key, 88 scoped_ptr<ClientSocketHandle> connection, 89 const BoundNetLog& net_log, 90 int certificate_error_code, 91 base::WeakPtr<SpdySession>* available_session, 92 bool is_secure); 93 94 // Find an available session for the given key, or NULL if there isn't one. 95 base::WeakPtr<SpdySession> FindAvailableSession(const SpdySessionKey& key, 96 const BoundNetLog& net_log); 97 98 // Remove all mappings and aliases for the given session, which must 99 // still be available. Except for in tests, this must be called by 100 // the given session itself. 101 void MakeSessionUnavailable( 102 const base::WeakPtr<SpdySession>& available_session); 103 104 // Removes an unavailable session from the pool. Except for in 105 // tests, this must be called by the given session itself. 106 void RemoveUnavailableSession( 107 const base::WeakPtr<SpdySession>& unavailable_session); 108 109 // Close only the currently existing SpdySessions with |error|. 110 // Let any new ones created while this method is running continue to 111 // live. 112 void CloseCurrentSessions(net::Error error); 113 114 // Close only the currently existing SpdySessions that are idle. 115 // Let any new ones created while this method is running continue to 116 // live. 117 void CloseCurrentIdleSessions(); 118 119 // Close all SpdySessions, including any new ones created in the process of 120 // closing the current ones. 121 void CloseAllSessions(); 122 123 // Creates a Value summary of the state of the spdy session pool. The caller 124 // responsible for deleting the returned value. 125 base::Value* SpdySessionPoolInfoToValue() const; 126 127 base::WeakPtr<HttpServerProperties> http_server_properties() { 128 return http_server_properties_; 129 } 130 131 // NetworkChangeNotifier::IPAddressObserver methods: 132 133 // We flush all idle sessions and release references to the active ones so 134 // they won't get re-used. The active ones will either complete successfully 135 // or error out due to the IP address change. 136 virtual void OnIPAddressChanged() OVERRIDE; 137 138 // SSLConfigService::Observer methods: 139 140 // We perform the same flushing as described above when SSL settings change. 141 virtual void OnSSLConfigChanged() OVERRIDE; 142 143 // CertDatabase::Observer methods: 144 145 // We perform the same flushing as described above when certificate database 146 // is changed. 147 virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE; 148 virtual void OnCACertChanged(const X509Certificate* cert) OVERRIDE; 149 150 private: 151 friend class SpdySessionPoolPeer; // For testing. 152 153 typedef std::set<SpdySession*> SessionSet; 154 typedef std::vector<base::WeakPtr<SpdySession> > WeakSessionList; 155 typedef std::map<SpdySessionKey, base::WeakPtr<SpdySession> > 156 AvailableSessionMap; 157 typedef std::map<IPEndPoint, SpdySessionKey> AliasMap; 158 159 // Returns true iff |session| is in |available_sessions_|. 160 bool IsSessionAvailable(const base::WeakPtr<SpdySession>& session) const; 161 162 // Returns a normalized version of the given key suitable for lookup 163 // into |available_sessions_|. 164 const SpdySessionKey& NormalizeListKey(const SpdySessionKey& key) const; 165 166 // Map the given key to the given session. There must not already be 167 // a mapping for |key|. 168 void MapKeyToAvailableSession(const SpdySessionKey& key, 169 const base::WeakPtr<SpdySession>& session); 170 171 // Returns an iterator into |available_sessions_| for the given key, 172 // which may be equal to |available_sessions_.end()|. 173 AvailableSessionMap::iterator LookupAvailableSessionByKey( 174 const SpdySessionKey& key); 175 176 // Remove the mapping of the given key, which must exist. 177 void UnmapKey(const SpdySessionKey& key); 178 179 // Remove all aliases for |key| from the aliases table. 180 void RemoveAliases(const SpdySessionKey& key); 181 182 // Get a copy of the current sessions as a list of WeakPtrs. Used by 183 // CloseCurrentSessionsHelper() below. 184 WeakSessionList GetCurrentSessions() const; 185 186 // Close only the currently existing SpdySessions with |error|. Let 187 // any new ones created while this method is running continue to 188 // live. If |idle_only| is true only idle sessions are closed. 189 void CloseCurrentSessionsHelper( 190 Error error, 191 const std::string& description, 192 bool idle_only); 193 194 const base::WeakPtr<HttpServerProperties> http_server_properties_; 195 196 // The set of all sessions. This is a superset of the sessions in 197 // |available_sessions_|. 198 // 199 // |sessions_| owns all its SpdySession objects. 200 SessionSet sessions_; 201 202 // This is a map of available sessions by key. A session may appear 203 // more than once in this map if it has aliases. 204 AvailableSessionMap available_sessions_; 205 206 // A map of IPEndPoint aliases for sessions. 207 AliasMap aliases_; 208 209 static bool g_force_single_domain; 210 211 const scoped_refptr<SSLConfigService> ssl_config_service_; 212 HostResolver* const resolver_; 213 214 // Defaults to true. May be controlled via SpdySessionPoolPeer for tests. 215 bool verify_domain_authentication_; 216 bool enable_sending_initial_data_; 217 bool force_single_domain_; 218 bool enable_ip_pooling_; 219 bool enable_compression_; 220 bool enable_ping_based_connection_checking_; 221 const NextProto default_protocol_; 222 size_t stream_initial_recv_window_size_; 223 size_t initial_max_concurrent_streams_; 224 size_t max_concurrent_streams_limit_; 225 TimeFunc time_func_; 226 227 // This SPDY proxy is allowed to push resources from origins that are 228 // different from those of their associated streams. 229 HostPortPair trusted_spdy_proxy_; 230 231 DISALLOW_COPY_AND_ASSIGN(SpdySessionPool); 232 }; 233 234 } // namespace net 235 236 #endif // NET_SPDY_SPDY_SESSION_POOL_H_ 237