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.
5 #ifndef NET_SPDY_SPDY_SESSION_POOL_H_
6 #define NET_SPDY_SPDY_SESSION_POOL_H_
12 #include "base/basictypes.h"
13 #include "base/gtest_prod_util.h"
14 #include "base/memory/ref_counted.h"
15 #include "net/base/cert_database.h"
16 #include "net/base/host_port_pair.h"
17 #include "net/base/ip_endpoint.h"
18 #include "net/base/net_errors.h"
19 #include "net/base/net_export.h"
20 #include "net/base/network_change_notifier.h"
21 #include "net/base/ssl_config_service.h"
22 #include "net/proxy/proxy_config.h"
23 #include "net/proxy/proxy_server.h"
29 class ClientSocketHandle
;
31 class HttpServerProperties
;
34 namespace test_spdy2
{
35 class SpdySessionPoolPeer
;
36 } // namespace test_spdy
38 namespace test_spdy3
{
39 class SpdySessionPoolPeer
;
40 } // namespace test_spdy
42 // This is a very simple pool for open SpdySessions.
43 class NET_EXPORT SpdySessionPool
44 : public NetworkChangeNotifier::IPAddressObserver
,
45 public SSLConfigService::Observer
,
46 public CertDatabase::Observer
{
48 SpdySessionPool(HostResolver
* host_resolver
,
49 SSLConfigService
* ssl_config_service
,
50 HttpServerProperties
* http_server_properties
,
51 const std::string
& trusted_spdy_proxy
);
52 virtual ~SpdySessionPool();
54 // Either returns an existing SpdySession or creates a new SpdySession for
56 scoped_refptr
<SpdySession
> Get(
57 const HostPortProxyPair
& host_port_proxy_pair
,
58 const BoundNetLog
& net_log
);
60 // Only returns a SpdySession if it already exists.
61 scoped_refptr
<SpdySession
> GetIfExists(
62 const HostPortProxyPair
& host_port_proxy_pair
,
63 const BoundNetLog
& net_log
);
65 // Set the maximum concurrent sessions per domain.
66 static void set_max_sessions_per_domain(int max
) {
68 g_max_sessions_per_domain
= max
;
71 // Builds a SpdySession from an existing SSL socket. Users should try
72 // calling Get() first to use an existing SpdySession so we don't get
73 // multiple SpdySessions per domain. Note that ownership of |connection| is
74 // transferred from the caller to the SpdySession.
75 // |certificate_error_code| is used to indicate the certificate error
76 // encountered when connecting the SSL socket. OK means there was no error.
77 // For testing, setting is_secure to false allows Spdy to connect with a
78 // pre-existing TCP socket.
79 // Returns OK on success, and the |spdy_session| will be provided.
80 // Returns an error on failure, and |spdy_session| will be NULL.
81 net::Error
GetSpdySessionFromSocket(
82 const HostPortProxyPair
& host_port_proxy_pair
,
83 ClientSocketHandle
* connection
,
84 const BoundNetLog
& net_log
,
85 int certificate_error_code
,
86 scoped_refptr
<SpdySession
>* spdy_session
,
89 // TODO(willchan): Consider renaming to HasReusableSession, since perhaps we
90 // should be creating a new session. WARNING: Because of IP connection pooling
91 // using the HostCache, if HasSession() returns true at one point, it does not
92 // imply the SpdySessionPool will still have a matching session in the near
93 // future, since the HostCache's entry may have expired.
94 bool HasSession(const HostPortProxyPair
& host_port_proxy_pair
) const;
96 // Close all SpdySessions, including any new ones created in the process of
97 // closing the current ones.
98 void CloseAllSessions();
99 // Close only the currently existing SpdySessions. Let any new ones created
101 void CloseCurrentSessions();
102 // Close only the idle SpdySessions.
103 void CloseIdleSessions();
105 // Removes a SpdySession from the SpdySessionPool. This should only be called
106 // by SpdySession, because otherwise session->state_ is not set to CLOSED.
107 void Remove(const scoped_refptr
<SpdySession
>& session
);
109 // Creates a Value summary of the state of the spdy session pool. The caller
110 // responsible for deleting the returned value.
111 base::Value
* SpdySessionPoolInfoToValue() const;
113 HttpServerProperties
* http_server_properties() {
114 return http_server_properties_
;
117 // NetworkChangeNotifier::IPAddressObserver methods:
119 // We flush all idle sessions and release references to the active ones so
120 // they won't get re-used. The active ones will either complete successfully
121 // or error out due to the IP address change.
122 virtual void OnIPAddressChanged() OVERRIDE
;
124 // SSLConfigService::Observer methods:
126 // We perform the same flushing as described above when SSL settings change.
127 virtual void OnSSLConfigChanged() OVERRIDE
;
129 // A debugging mode where we compress all accesses through a single domain.
130 static void ForceSingleDomain() { g_force_single_domain
= true; }
132 // Controls whether the pool allows use of a common session for domains
133 // which share IP address resolutions.
134 static void enable_ip_pooling(bool value
) { g_enable_ip_pooling
= value
; }
136 // CertDatabase::Observer methods:
137 virtual void OnCertAdded(const X509Certificate
* cert
) OVERRIDE
;
138 virtual void OnCertTrustChanged(const X509Certificate
* cert
) OVERRIDE
;
141 friend class test_spdy2::SpdySessionPoolPeer
; // For testing.
142 friend class test_spdy3::SpdySessionPoolPeer
; // For testing.
143 friend class SpdyNetworkTransactionSpdy2Test
; // For testing.
144 friend class SpdyNetworkTransactionSpdy3Test
; // For testing.
145 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionSpdy2Test
,
146 WindowUpdateOverflow
);
147 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionSpdy3Test
,
148 WindowUpdateOverflow
);
150 typedef std::list
<scoped_refptr
<SpdySession
> > SpdySessionList
;
151 typedef std::map
<HostPortProxyPair
, SpdySessionList
*> SpdySessionsMap
;
152 typedef std::map
<IPEndPoint
, HostPortProxyPair
> SpdyAliasMap
;
155 scoped_refptr
<SpdySession
> GetInternal(
156 const HostPortProxyPair
& host_port_proxy_pair
,
157 const BoundNetLog
& net_log
,
158 bool only_use_existing_sessions
);
159 scoped_refptr
<SpdySession
> GetExistingSession(
160 SpdySessionList
* list
,
161 const BoundNetLog
& net_log
) const;
162 scoped_refptr
<SpdySession
> GetFromAlias(
163 const HostPortProxyPair
& host_port_proxy_pair
,
164 const BoundNetLog
& net_log
,
165 bool record_histograms
) const;
167 // Helper functions for manipulating the lists.
168 const HostPortProxyPair
& NormalizeListPair(
169 const HostPortProxyPair
& host_port_proxy_pair
) const;
170 SpdySessionList
* AddSessionList(
171 const HostPortProxyPair
& host_port_proxy_pair
);
172 SpdySessionList
* GetSessionList(
173 const HostPortProxyPair
& host_port_proxy_pair
) const;
174 void RemoveSessionList(const HostPortProxyPair
& host_port_proxy_pair
);
176 // Does a DNS cache lookup for |pair|, and returns the |addresses| found.
177 // Returns true if addresses found, false otherwise.
178 bool LookupAddresses(const HostPortProxyPair
& pair
,
179 const BoundNetLog
& net_log
,
180 AddressList
* addresses
) const;
182 // Add |address| as an IP-equivalent address for |pair|.
183 void AddAlias(const IPEndPoint
& address
, const HostPortProxyPair
& pair
);
185 // Remove all aliases for |pair| from the aliases table.
186 void RemoveAliases(const HostPortProxyPair
& pair
);
188 // Removes |session| from the session list associated with |pair|.
189 // Returns true if the session was removed, false otherwise.
190 bool RemoveFromSessionList(const scoped_refptr
<SpdySession
>& session
,
191 const HostPortProxyPair
& pair
);
193 HttpServerProperties
* const http_server_properties_
;
195 // This is our weak session pool - one session per domain.
196 SpdySessionsMap sessions_
;
197 // A map of IPEndPoint aliases for sessions.
198 SpdyAliasMap aliases_
;
200 static size_t g_max_sessions_per_domain
;
201 static bool g_force_single_domain
;
202 static bool g_enable_ip_pooling
;
204 const scoped_refptr
<SSLConfigService
> ssl_config_service_
;
205 HostResolver
* const resolver_
;
207 // Defaults to true. May be controlled via SpdySessionPoolPeer for tests.
208 bool verify_domain_authentication_
;
210 bool enable_sending_initial_settings_
;
212 // This SPDY proxy is allowed to push resources from origins that are
213 // different from those of their associated streams.
214 HostPortPair trusted_spdy_proxy_
;
216 DISALLOW_COPY_AND_ASSIGN(SpdySessionPool
);
221 #endif // NET_SPDY_SPDY_SESSION_POOL_H_