Evict resources from resource pool after timeout
[chromium-blink-merge.git] / net / socket / client_socket_pool_manager_impl.cc
blob9dbb19e9c622579513b3a3eaff2f30b69a37b72a
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 #include "net/socket/client_socket_pool_manager_impl.h"
7 #include "base/logging.h"
8 #include "base/values.h"
9 #include "net/http/http_network_session.h"
10 #include "net/http/http_proxy_client_socket_pool.h"
11 #include "net/socket/socks_client_socket_pool.h"
12 #include "net/socket/ssl_client_socket_pool.h"
13 #include "net/socket/transport_client_socket_pool.h"
14 #include "net/socket/websocket_transport_client_socket_pool.h"
15 #include "net/ssl/ssl_config_service.h"
17 namespace net {
19 namespace {
21 // Appends information about all |socket_pools| to the end of |list|.
22 template <class MapType>
23 void AddSocketPoolsToList(base::ListValue* list,
24 const MapType& socket_pools,
25 const std::string& type,
26 bool include_nested_pools) {
27 for (typename MapType::const_iterator it = socket_pools.begin();
28 it != socket_pools.end(); it++) {
29 list->Append(it->second->GetInfoAsValue(it->first.ToString(),
30 type,
31 include_nested_pools));
35 } // namespace
37 ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
38 NetLog* net_log,
39 ClientSocketFactory* socket_factory,
40 HostResolver* host_resolver,
41 CertVerifier* cert_verifier,
42 ChannelIDService* channel_id_service,
43 TransportSecurityState* transport_security_state,
44 CTVerifier* cert_transparency_verifier,
45 CertPolicyEnforcer* cert_policy_enforcer,
46 const std::string& ssl_session_cache_shard,
47 SSLConfigService* ssl_config_service,
48 HttpNetworkSession::SocketPoolType pool_type)
49 : net_log_(net_log),
50 socket_factory_(socket_factory),
51 host_resolver_(host_resolver),
52 cert_verifier_(cert_verifier),
53 channel_id_service_(channel_id_service),
54 transport_security_state_(transport_security_state),
55 cert_transparency_verifier_(cert_transparency_verifier),
56 cert_policy_enforcer_(cert_policy_enforcer),
57 ssl_session_cache_shard_(ssl_session_cache_shard),
58 ssl_config_service_(ssl_config_service),
59 pool_type_(pool_type),
60 transport_socket_pool_(
61 pool_type == HttpNetworkSession::WEBSOCKET_SOCKET_POOL
62 ? new WebSocketTransportClientSocketPool(
63 max_sockets_per_pool(pool_type),
64 max_sockets_per_group(pool_type),
65 host_resolver,
66 socket_factory_,
67 net_log)
68 : new TransportClientSocketPool(max_sockets_per_pool(pool_type),
69 max_sockets_per_group(pool_type),
70 host_resolver,
71 socket_factory_,
72 net_log)),
73 ssl_socket_pool_(new SSLClientSocketPool(max_sockets_per_pool(pool_type),
74 max_sockets_per_group(pool_type),
75 cert_verifier,
76 channel_id_service,
77 transport_security_state,
78 cert_transparency_verifier,
79 cert_policy_enforcer,
80 ssl_session_cache_shard,
81 socket_factory,
82 transport_socket_pool_.get(),
83 NULL /* no socks proxy */,
84 NULL /* no http proxy */,
85 ssl_config_service,
86 net_log)) {
87 CertDatabase::GetInstance()->AddObserver(this);
90 ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() {
91 CertDatabase::GetInstance()->RemoveObserver(this);
94 void ClientSocketPoolManagerImpl::FlushSocketPoolsWithError(int error) {
95 // Flush the highest level pools first, since higher level pools may release
96 // stuff to the lower level pools.
98 for (SSLSocketPoolMap::const_iterator it =
99 ssl_socket_pools_for_proxies_.begin();
100 it != ssl_socket_pools_for_proxies_.end();
101 ++it)
102 it->second->FlushWithError(error);
104 for (HTTPProxySocketPoolMap::const_iterator it =
105 http_proxy_socket_pools_.begin();
106 it != http_proxy_socket_pools_.end();
107 ++it)
108 it->second->FlushWithError(error);
110 for (SSLSocketPoolMap::const_iterator it =
111 ssl_socket_pools_for_https_proxies_.begin();
112 it != ssl_socket_pools_for_https_proxies_.end();
113 ++it)
114 it->second->FlushWithError(error);
116 for (TransportSocketPoolMap::const_iterator it =
117 transport_socket_pools_for_https_proxies_.begin();
118 it != transport_socket_pools_for_https_proxies_.end();
119 ++it)
120 it->second->FlushWithError(error);
122 for (TransportSocketPoolMap::const_iterator it =
123 transport_socket_pools_for_http_proxies_.begin();
124 it != transport_socket_pools_for_http_proxies_.end();
125 ++it)
126 it->second->FlushWithError(error);
128 for (SOCKSSocketPoolMap::const_iterator it =
129 socks_socket_pools_.begin();
130 it != socks_socket_pools_.end();
131 ++it)
132 it->second->FlushWithError(error);
134 for (TransportSocketPoolMap::const_iterator it =
135 transport_socket_pools_for_socks_proxies_.begin();
136 it != transport_socket_pools_for_socks_proxies_.end();
137 ++it)
138 it->second->FlushWithError(error);
140 ssl_socket_pool_->FlushWithError(error);
141 transport_socket_pool_->FlushWithError(error);
144 void ClientSocketPoolManagerImpl::CloseIdleSockets() {
145 // Close sockets in the highest level pools first, since higher level pools'
146 // sockets may release stuff to the lower level pools.
147 for (SSLSocketPoolMap::const_iterator it =
148 ssl_socket_pools_for_proxies_.begin();
149 it != ssl_socket_pools_for_proxies_.end();
150 ++it)
151 it->second->CloseIdleSockets();
153 for (HTTPProxySocketPoolMap::const_iterator it =
154 http_proxy_socket_pools_.begin();
155 it != http_proxy_socket_pools_.end();
156 ++it)
157 it->second->CloseIdleSockets();
159 for (SSLSocketPoolMap::const_iterator it =
160 ssl_socket_pools_for_https_proxies_.begin();
161 it != ssl_socket_pools_for_https_proxies_.end();
162 ++it)
163 it->second->CloseIdleSockets();
165 for (TransportSocketPoolMap::const_iterator it =
166 transport_socket_pools_for_https_proxies_.begin();
167 it != transport_socket_pools_for_https_proxies_.end();
168 ++it)
169 it->second->CloseIdleSockets();
171 for (TransportSocketPoolMap::const_iterator it =
172 transport_socket_pools_for_http_proxies_.begin();
173 it != transport_socket_pools_for_http_proxies_.end();
174 ++it)
175 it->second->CloseIdleSockets();
177 for (SOCKSSocketPoolMap::const_iterator it =
178 socks_socket_pools_.begin();
179 it != socks_socket_pools_.end();
180 ++it)
181 it->second->CloseIdleSockets();
183 for (TransportSocketPoolMap::const_iterator it =
184 transport_socket_pools_for_socks_proxies_.begin();
185 it != transport_socket_pools_for_socks_proxies_.end();
186 ++it)
187 it->second->CloseIdleSockets();
189 ssl_socket_pool_->CloseIdleSockets();
190 transport_socket_pool_->CloseIdleSockets();
193 TransportClientSocketPool*
194 ClientSocketPoolManagerImpl::GetTransportSocketPool() {
195 return transport_socket_pool_.get();
198 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSSLSocketPool() {
199 return ssl_socket_pool_.get();
202 SOCKSClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSOCKSProxy(
203 const HostPortPair& socks_proxy) {
204 SOCKSSocketPoolMap::const_iterator it = socks_socket_pools_.find(socks_proxy);
205 if (it != socks_socket_pools_.end()) {
206 DCHECK(ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
207 return it->second;
210 DCHECK(!ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
212 std::pair<TransportSocketPoolMap::iterator, bool> tcp_ret =
213 transport_socket_pools_for_socks_proxies_.insert(
214 std::make_pair(
215 socks_proxy,
216 new TransportClientSocketPool(
217 max_sockets_per_proxy_server(pool_type_),
218 max_sockets_per_group(pool_type_),
219 host_resolver_,
220 socket_factory_,
221 net_log_)));
222 DCHECK(tcp_ret.second);
224 std::pair<SOCKSSocketPoolMap::iterator, bool> ret =
225 socks_socket_pools_.insert(
226 std::make_pair(socks_proxy, new SOCKSClientSocketPool(
227 max_sockets_per_proxy_server(pool_type_),
228 max_sockets_per_group(pool_type_),
229 host_resolver_,
230 tcp_ret.first->second,
231 net_log_)));
233 return ret.first->second;
236 HttpProxyClientSocketPool*
237 ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
238 const HostPortPair& http_proxy) {
239 HTTPProxySocketPoolMap::const_iterator it =
240 http_proxy_socket_pools_.find(http_proxy);
241 if (it != http_proxy_socket_pools_.end()) {
242 DCHECK(ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
243 DCHECK(ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
244 DCHECK(ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
245 return it->second;
248 DCHECK(!ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
249 DCHECK(!ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
250 DCHECK(!ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
252 std::pair<TransportSocketPoolMap::iterator, bool> tcp_http_ret =
253 transport_socket_pools_for_http_proxies_.insert(
254 std::make_pair(
255 http_proxy,
256 new TransportClientSocketPool(
257 max_sockets_per_proxy_server(pool_type_),
258 max_sockets_per_group(pool_type_),
259 host_resolver_,
260 socket_factory_,
261 net_log_)));
262 DCHECK(tcp_http_ret.second);
264 std::pair<TransportSocketPoolMap::iterator, bool> tcp_https_ret =
265 transport_socket_pools_for_https_proxies_.insert(
266 std::make_pair(
267 http_proxy,
268 new TransportClientSocketPool(
269 max_sockets_per_proxy_server(pool_type_),
270 max_sockets_per_group(pool_type_),
271 host_resolver_,
272 socket_factory_,
273 net_log_)));
274 DCHECK(tcp_https_ret.second);
276 std::pair<SSLSocketPoolMap::iterator, bool> ssl_https_ret =
277 ssl_socket_pools_for_https_proxies_.insert(std::make_pair(
278 http_proxy, new SSLClientSocketPool(
279 max_sockets_per_proxy_server(pool_type_),
280 max_sockets_per_group(pool_type_), cert_verifier_,
281 channel_id_service_, transport_security_state_,
282 cert_transparency_verifier_, cert_policy_enforcer_,
283 ssl_session_cache_shard_, socket_factory_,
284 tcp_https_ret.first->second /* https proxy */,
285 NULL /* no socks proxy */, NULL /* no http proxy */,
286 ssl_config_service_.get(), net_log_)));
287 DCHECK(tcp_https_ret.second);
289 std::pair<HTTPProxySocketPoolMap::iterator, bool> ret =
290 http_proxy_socket_pools_.insert(
291 std::make_pair(
292 http_proxy,
293 new HttpProxyClientSocketPool(
294 max_sockets_per_proxy_server(pool_type_),
295 max_sockets_per_group(pool_type_),
296 tcp_http_ret.first->second,
297 ssl_https_ret.first->second,
298 net_log_)));
300 return ret.first->second;
303 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSSLWithProxy(
304 const HostPortPair& proxy_server) {
305 SSLSocketPoolMap::const_iterator it =
306 ssl_socket_pools_for_proxies_.find(proxy_server);
307 if (it != ssl_socket_pools_for_proxies_.end())
308 return it->second;
310 SSLClientSocketPool* new_pool = new SSLClientSocketPool(
311 max_sockets_per_proxy_server(pool_type_),
312 max_sockets_per_group(pool_type_), cert_verifier_, channel_id_service_,
313 transport_security_state_, cert_transparency_verifier_,
314 cert_policy_enforcer_, ssl_session_cache_shard_, socket_factory_,
315 NULL, /* no tcp pool, we always go through a proxy */
316 GetSocketPoolForSOCKSProxy(proxy_server),
317 GetSocketPoolForHTTPProxy(proxy_server), ssl_config_service_.get(),
318 net_log_);
320 std::pair<SSLSocketPoolMap::iterator, bool> ret =
321 ssl_socket_pools_for_proxies_.insert(std::make_pair(proxy_server,
322 new_pool));
324 return ret.first->second;
327 scoped_ptr<base::Value> ClientSocketPoolManagerImpl::SocketPoolInfoToValue()
328 const {
329 scoped_ptr<base::ListValue> list(new base::ListValue());
330 list->Append(transport_socket_pool_->GetInfoAsValue("transport_socket_pool",
331 "transport_socket_pool",
332 false));
333 // Third parameter is false because |ssl_socket_pool_| uses
334 // |transport_socket_pool_| internally, and do not want to add it a second
335 // time.
336 list->Append(ssl_socket_pool_->GetInfoAsValue("ssl_socket_pool",
337 "ssl_socket_pool",
338 false));
339 AddSocketPoolsToList(list.get(), http_proxy_socket_pools_,
340 "http_proxy_socket_pool", true);
341 AddSocketPoolsToList(list.get(), socks_socket_pools_, "socks_socket_pool",
342 true);
344 // Third parameter is false because |ssl_socket_pools_for_proxies_| use
345 // socket pools in |http_proxy_socket_pools_| and |socks_socket_pools_|.
346 AddSocketPoolsToList(list.get(), ssl_socket_pools_for_proxies_,
347 "ssl_socket_pool_for_proxies", false);
348 return list.Pass();
351 void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate* cert) {
352 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
355 void ClientSocketPoolManagerImpl::OnCACertChanged(
356 const X509Certificate* cert) {
357 // We should flush the socket pools if we removed trust from a
358 // cert, because a previously trusted server may have become
359 // untrusted.
361 // We should not flush the socket pools if we added trust to a
362 // cert.
364 // Since the OnCACertChanged method doesn't tell us what
365 // kind of change it is, we have to flush the socket
366 // pools to be safe.
367 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
370 } // namespace net