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_compression, 55 bool enable_ping_based_connection_checking, 56 NextProto default_protocol, 57 size_t stream_initial_recv_window_size, 58 size_t initial_max_concurrent_streams, 59 size_t max_concurrent_streams_limit, 60 SpdySessionPool::TimeFunc time_func, 61 const std::string& trusted_spdy_proxy); 62 virtual ~SpdySessionPool(); 63 64 // In the functions below, a session is "available" if this pool has 65 // a reference to it and there is some SpdySessionKey for which 66 // FindAvailableSession() will return it. A session is "unavailable" 67 // if this pool has a reference to it but it won't be returned by 68 // FindAvailableSession() for any SpdySessionKey; for example, this 69 // can happen when a session receives a GOAWAY frame and is still 70 // processing existing streams. 71 72 // Create a new SPDY session from an existing socket. There must 73 // not already be a session for the given key. This pool must have 74 // been constructed with a valid |default_protocol| value. 75 // 76 // |is_secure| can be false for testing or when SPDY is configured 77 // to work with non-secure sockets. If |is_secure| is true, 78 // |certificate_error_code| indicates that the certificate error 79 // encountered when connecting the SSL socket, with OK meaning there 80 // was no error. 81 // 82 // Returns the new SpdySession. Note that the SpdySession begins reading from 83 // |connection| on a subsequent event loop iteration, so it may be closed 84 // immediately afterwards if the first read of |connection| fails. 85 base::WeakPtr<SpdySession> CreateAvailableSessionFromSocket( 86 const SpdySessionKey& key, 87 scoped_ptr<ClientSocketHandle> connection, 88 const BoundNetLog& net_log, 89 int certificate_error_code, 90 bool is_secure); 91 92 // Find an available session for the given key, or NULL if there isn't one. 93 base::WeakPtr<SpdySession> FindAvailableSession(const SpdySessionKey& key, 94 const BoundNetLog& net_log); 95 96 // Remove all mappings and aliases for the given session, which must 97 // still be available. Except for in tests, this must be called by 98 // the given session itself. 99 void MakeSessionUnavailable( 100 const base::WeakPtr<SpdySession>& available_session); 101 102 // Removes an unavailable session from the pool. Except for in 103 // tests, this must be called by the given session itself. 104 void RemoveUnavailableSession( 105 const base::WeakPtr<SpdySession>& unavailable_session); 106 107 // Close only the currently existing SpdySessions with |error|. 108 // Let any new ones created while this method is running continue to 109 // live. 110 void CloseCurrentSessions(net::Error error); 111 112 // Close only the currently existing SpdySessions that are idle. 113 // Let any new ones created while this method is running continue to 114 // live. 115 void CloseCurrentIdleSessions(); 116 117 // Close all SpdySessions, including any new ones created in the process of 118 // closing the current ones. 119 void CloseAllSessions(); 120 121 // Creates a Value summary of the state of the spdy session pool. The caller 122 // responsible for deleting the returned value. 123 base::Value* SpdySessionPoolInfoToValue() const; 124 125 base::WeakPtr<HttpServerProperties> http_server_properties() { 126 return http_server_properties_; 127 } 128 129 // NetworkChangeNotifier::IPAddressObserver methods: 130 131 // We flush all idle sessions and release references to the active ones so 132 // they won't get re-used. The active ones will either complete successfully 133 // or error out due to the IP address change. 134 virtual void OnIPAddressChanged() OVERRIDE; 135 136 // SSLConfigService::Observer methods: 137 138 // We perform the same flushing as described above when SSL settings change. 139 virtual void OnSSLConfigChanged() OVERRIDE; 140 141 // CertDatabase::Observer methods: 142 143 // We perform the same flushing as described above when certificate database 144 // is changed. 145 virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE; 146 virtual void OnCACertChanged(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_compression_; 217 bool enable_ping_based_connection_checking_; 218 const NextProto default_protocol_; 219 size_t stream_initial_recv_window_size_; 220 size_t initial_max_concurrent_streams_; 221 size_t max_concurrent_streams_limit_; 222 TimeFunc time_func_; 223 224 // This SPDY proxy is allowed to push resources from origins that are 225 // different from those of their associated streams. 226 HostPortPair trusted_spdy_proxy_; 227 228 DISALLOW_COPY_AND_ASSIGN(SpdySessionPool); 229 }; 230 231 } // namespace net 232 233 #endif // NET_SPDY_SPDY_SESSION_POOL_H_ 234