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 29namespace net { 30 31class AddressList; 32class BoundNetLog; 33class ClientSocketHandle; 34class HostResolver; 35class HttpServerProperties; 36class SpdySession; 37class TransportSecurityState; 38 39// This is a very simple pool for open SpdySessions. 40class NET_EXPORT SpdySessionPool 41 : public NetworkChangeNotifier::IPAddressObserver, 42 public SSLConfigService::Observer, 43 public CertDatabase::Observer { 44 public: 45 typedef base::TimeTicks (*TimeFunc)(void); 46 47 // |default_protocol| may be kProtoUnknown (e.g., if SPDY is 48 // disabled), in which case it's set to a default value. Otherwise, 49 // it must be a SPDY protocol. 50 SpdySessionPool( 51 HostResolver* host_resolver, 52 SSLConfigService* ssl_config_service, 53 const base::WeakPtr<HttpServerProperties>& http_server_properties, 54 TransportSecurityState* transport_security_state, 55 bool force_single_domain, 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 // Returns the new SpdySession. Note that the SpdySession begins reading from 85 // |connection| on a subsequent event loop iteration, so it may be closed 86 // immediately afterwards if the first read of |connection| fails. 87 base::WeakPtr<SpdySession> CreateAvailableSessionFromSocket( 88 const SpdySessionKey& key, 89 scoped_ptr<ClientSocketHandle> connection, 90 const BoundNetLog& net_log, 91 int certificate_error_code, 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 TransportSecurityState* transport_security_state_; 197 198 // The set of all sessions. This is a superset of the sessions in 199 // |available_sessions_|. 200 // 201 // |sessions_| owns all its SpdySession objects. 202 SessionSet sessions_; 203 204 // This is a map of available sessions by key. A session may appear 205 // more than once in this map if it has aliases. 206 AvailableSessionMap available_sessions_; 207 208 // A map of IPEndPoint aliases for sessions. 209 AliasMap aliases_; 210 211 static bool g_force_single_domain; 212 213 const scoped_refptr<SSLConfigService> ssl_config_service_; 214 HostResolver* const resolver_; 215 216 // Defaults to true. May be controlled via SpdySessionPoolPeer for tests. 217 bool verify_domain_authentication_; 218 bool enable_sending_initial_data_; 219 bool force_single_domain_; 220 bool enable_compression_; 221 bool enable_ping_based_connection_checking_; 222 const NextProto default_protocol_; 223 size_t stream_initial_recv_window_size_; 224 size_t initial_max_concurrent_streams_; 225 size_t max_concurrent_streams_limit_; 226 TimeFunc time_func_; 227 228 // This SPDY proxy is allowed to push resources from origins that are 229 // different from those of their associated streams. 230 HostPortPair trusted_spdy_proxy_; 231 232 DISALLOW_COPY_AND_ASSIGN(SpdySessionPool); 233}; 234 235} // namespace net 236 237#endif // NET_SPDY_SPDY_SESSION_POOL_H_ 238