blob: 0467583eefa0f8ea73936c0adbadc51d79ad58b9 [file] [log] [blame]
David Ghandehari9e5b5872016-07-28 09:50:04 -07001// 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 <list>
10#include <string>
11
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"
24#include "net/socket/next_proto.h"
25
26namespace net {
27
28class AddressList;
29class BoundNetLog;
30class ClientSocketHandle;
31class HostResolver;
32class HttpServerProperties;
33class SpdySession;
34
35namespace test_spdy2 {
36class SpdySessionPoolPeer;
37} // namespace test_spdy
38
39namespace test_spdy3 {
40class SpdySessionPoolPeer;
41} // namespace test_spdy
42
43// This is a very simple pool for open SpdySessions.
44class NET_EXPORT SpdySessionPool
45 : public NetworkChangeNotifier::IPAddressObserver,
46 public SSLConfigService::Observer,
47 public CertDatabase::Observer {
48 public:
49 typedef base::TimeTicks (*TimeFunc)(void);
50
51 SpdySessionPool(HostResolver* host_resolver,
52 SSLConfigService* ssl_config_service,
53 HttpServerProperties* http_server_properties,
54 size_t max_sessions_per_domain,
55 bool force_single_domain,
56 bool enable_ip_pooling,
57 bool enable_credential_frames,
58 bool enable_compression,
59 bool enable_ping_based_connection_checking,
60 NextProto default_protocol,
61 size_t default_initial_recv_window_size,
62 size_t initial_max_concurrent_streams,
63 size_t max_concurrent_streams_limit,
64 SpdySessionPool::TimeFunc time_func,
65 const std::string& trusted_spdy_proxy);
66 virtual ~SpdySessionPool();
67
68 // Either returns an existing SpdySession or creates a new SpdySession for
69 // use.
70 scoped_refptr<SpdySession> Get(
71 const HostPortProxyPair& host_port_proxy_pair,
72 const BoundNetLog& net_log);
73
74 // Only returns a SpdySession if it already exists.
75 scoped_refptr<SpdySession> GetIfExists(
76 const HostPortProxyPair& host_port_proxy_pair,
77 const BoundNetLog& net_log);
78
79 // Builds a SpdySession from an existing SSL socket. Users should try
80 // calling Get() first to use an existing SpdySession so we don't get
81 // multiple SpdySessions per domain. Note that ownership of |connection| is
82 // transferred from the caller to the SpdySession.
83 // |certificate_error_code| is used to indicate the certificate error
84 // encountered when connecting the SSL socket. OK means there was no error.
85 // For testing, setting is_secure to false allows Spdy to connect with a
86 // pre-existing TCP socket.
87 // Returns OK on success, and the |spdy_session| will be provided.
88 // Returns an error on failure, and |spdy_session| will be NULL.
89 net::Error GetSpdySessionFromSocket(
90 const HostPortProxyPair& host_port_proxy_pair,
91 ClientSocketHandle* connection,
92 const BoundNetLog& net_log,
93 int certificate_error_code,
94 scoped_refptr<SpdySession>* spdy_session,
95 bool is_secure);
96
97 // TODO(willchan): Consider renaming to HasReusableSession, since perhaps we
98 // should be creating a new session. WARNING: Because of IP connection pooling
99 // using the HostCache, if HasSession() returns true at one point, it does not
100 // imply the SpdySessionPool will still have a matching session in the near
101 // future, since the HostCache's entry may have expired.
102 bool HasSession(const HostPortProxyPair& host_port_proxy_pair) const;
103
104 // Close all SpdySessions, including any new ones created in the process of
105 // closing the current ones.
106 void CloseAllSessions();
107 // Close only the currently existing SpdySessions with |error|.
108 // Let any new ones created continue to live.
109 void CloseCurrentSessions(net::Error error);
110 // Close only the idle SpdySessions.
111 void CloseIdleSessions();
112
113 // Removes a SpdySession from the SpdySessionPool. This should only be called
114 // by SpdySession, because otherwise session->state_ is not set to CLOSED.
115 void Remove(const scoped_refptr<SpdySession>& session);
116
117 // Creates a Value summary of the state of the spdy session pool. The caller
118 // responsible for deleting the returned value.
119 base::Value* SpdySessionPoolInfoToValue() const;
120
121 HttpServerProperties* http_server_properties() {
122 return http_server_properties_;
123 }
124
125 // NetworkChangeNotifier::IPAddressObserver methods:
126
127 // We flush all idle sessions and release references to the active ones so
128 // they won't get re-used. The active ones will either complete successfully
129 // or error out due to the IP address change.
130 virtual void OnIPAddressChanged() OVERRIDE;
131
132 // SSLConfigService::Observer methods:
133
134 // We perform the same flushing as described above when SSL settings change.
135 virtual void OnSSLConfigChanged() OVERRIDE;
136
137 // CertDatabase::Observer methods:
138 virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE;
139 virtual void OnCertTrustChanged(const X509Certificate* cert) OVERRIDE;
140
141 private:
142 friend class test_spdy2::SpdySessionPoolPeer; // For testing.
143 friend class test_spdy3::SpdySessionPoolPeer; // For testing.
144 friend class SpdyNetworkTransactionSpdy2Test; // For testing.
145 friend class SpdyNetworkTransactionSpdy3Test; // For testing.
146 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionSpdy2Test,
147 WindowUpdateOverflow);
148 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionSpdy3Test,
149 WindowUpdateOverflow);
150
151 typedef std::list<scoped_refptr<SpdySession> > SpdySessionList;
152 typedef std::map<HostPortProxyPair, SpdySessionList*> SpdySessionsMap;
153 typedef std::map<IPEndPoint, HostPortProxyPair> SpdyAliasMap;
154
155
156 scoped_refptr<SpdySession> GetInternal(
157 const HostPortProxyPair& host_port_proxy_pair,
158 const BoundNetLog& net_log,
159 bool only_use_existing_sessions);
160 scoped_refptr<SpdySession> GetExistingSession(
161 SpdySessionList* list,
162 const BoundNetLog& net_log) const;
163 scoped_refptr<SpdySession> GetFromAlias(
164 const HostPortProxyPair& host_port_proxy_pair,
165 const BoundNetLog& net_log,
166 bool record_histograms) const;
167
168 // Helper functions for manipulating the lists.
169 const HostPortProxyPair& NormalizeListPair(
170 const HostPortProxyPair& host_port_proxy_pair) const;
171 SpdySessionList* AddSessionList(
172 const HostPortProxyPair& host_port_proxy_pair);
173 SpdySessionList* GetSessionList(
174 const HostPortProxyPair& host_port_proxy_pair) const;
175 void RemoveSessionList(const HostPortProxyPair& host_port_proxy_pair);
176
177 // Does a DNS cache lookup for |pair|, and returns the |addresses| found.
178 // Returns true if addresses found, false otherwise.
179 bool LookupAddresses(const HostPortProxyPair& pair,
180 const BoundNetLog& net_log,
181 AddressList* addresses) const;
182
183 // Add |address| as an IP-equivalent address for |pair|.
184 void AddAlias(const IPEndPoint& address, const HostPortProxyPair& pair);
185
186 // Remove all aliases for |pair| from the aliases table.
187 void RemoveAliases(const HostPortProxyPair& pair);
188
189 // Removes |session| from the session list associated with |pair|.
190 // Returns true if the session was removed, false otherwise.
191 bool RemoveFromSessionList(const scoped_refptr<SpdySession>& session,
192 const HostPortProxyPair& pair);
193
194 HttpServerProperties* const http_server_properties_;
195
196 // This is our weak session pool - one session per domain.
197 SpdySessionsMap sessions_;
198 // A map of IPEndPoint aliases for sessions.
199 SpdyAliasMap aliases_;
200
201 static bool g_force_single_domain;
202
203 const scoped_refptr<SSLConfigService> ssl_config_service_;
204 HostResolver* const resolver_;
205
206 // Defaults to true. May be controlled via SpdySessionPoolPeer for tests.
207 bool verify_domain_authentication_;
208 bool enable_sending_initial_settings_;
209 size_t max_sessions_per_domain_;
210 bool force_single_domain_;
211 bool enable_ip_pooling_;
212 bool enable_credential_frames_;
213 bool enable_compression_;
214 bool enable_ping_based_connection_checking_;
215 NextProto default_protocol_;
216 size_t initial_recv_window_size_;
217 size_t initial_max_concurrent_streams_;
218 size_t max_concurrent_streams_limit_;
219 TimeFunc time_func_;
220
221 // This SPDY proxy is allowed to push resources from origins that are
222 // different from those of their associated streams.
223 HostPortPair trusted_spdy_proxy_;
224
225 DISALLOW_COPY_AND_ASSIGN(SpdySessionPool);
226};
227
228} // namespace net
229
230#endif // NET_SPDY_SPDY_SESSION_POOL_H_