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