Revert 233414 "x11: Move XInput2 availability information out of..."
[chromium-blink-merge.git] / net / socket / client_socket_pool_manager_impl.cc
blob35e7564ad2e12321738589318dc936607069b51f
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/ssl/ssl_config_service.h"
16 namespace net {
18 namespace {
20 // Appends information about all |socket_pools| to the end of |list|.
21 template <class MapType>
22 void AddSocketPoolsToList(base::ListValue* list,
23 const MapType& socket_pools,
24 const std::string& type,
25 bool include_nested_pools) {
26 for (typename MapType::const_iterator it = socket_pools.begin();
27 it != socket_pools.end(); it++) {
28 list->Append(it->second->GetInfoAsValue(it->first.ToString(),
29 type,
30 include_nested_pools));
34 } // namespace
36 ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
37 NetLog* net_log,
38 ClientSocketFactory* socket_factory,
39 HostResolver* host_resolver,
40 CertVerifier* cert_verifier,
41 ServerBoundCertService* server_bound_cert_service,
42 TransportSecurityState* transport_security_state,
43 const std::string& ssl_session_cache_shard,
44 ProxyService* proxy_service,
45 SSLConfigService* ssl_config_service,
46 HttpNetworkSession::SocketPoolType pool_type)
47 : net_log_(net_log),
48 socket_factory_(socket_factory),
49 host_resolver_(host_resolver),
50 cert_verifier_(cert_verifier),
51 server_bound_cert_service_(server_bound_cert_service),
52 transport_security_state_(transport_security_state),
53 ssl_session_cache_shard_(ssl_session_cache_shard),
54 proxy_service_(proxy_service),
55 ssl_config_service_(ssl_config_service),
56 pool_type_(pool_type),
57 transport_pool_histograms_("TCP"),
58 transport_socket_pool_(new TransportClientSocketPool(
59 max_sockets_per_pool(pool_type), max_sockets_per_group(pool_type),
60 &transport_pool_histograms_,
61 host_resolver,
62 socket_factory_,
63 net_log)),
64 ssl_pool_histograms_("SSL2"),
65 ssl_socket_pool_(new SSLClientSocketPool(
66 max_sockets_per_pool(pool_type), max_sockets_per_group(pool_type),
67 &ssl_pool_histograms_,
68 host_resolver,
69 cert_verifier,
70 server_bound_cert_service,
71 transport_security_state,
72 ssl_session_cache_shard,
73 socket_factory,
74 transport_socket_pool_.get(),
75 NULL /* no socks proxy */,
76 NULL /* no http proxy */,
77 ssl_config_service,
78 net_log)),
79 transport_for_socks_pool_histograms_("TCPforSOCKS"),
80 socks_pool_histograms_("SOCK"),
81 transport_for_http_proxy_pool_histograms_("TCPforHTTPProxy"),
82 transport_for_https_proxy_pool_histograms_("TCPforHTTPSProxy"),
83 ssl_for_https_proxy_pool_histograms_("SSLforHTTPSProxy"),
84 http_proxy_pool_histograms_("HTTPProxy"),
85 ssl_socket_pool_for_proxies_histograms_("SSLForProxies") {
86 CertDatabase::GetInstance()->AddObserver(this);
89 ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() {
90 CertDatabase::GetInstance()->RemoveObserver(this);
93 void ClientSocketPoolManagerImpl::FlushSocketPoolsWithError(int error) {
94 // Flush the highest level pools first, since higher level pools may release
95 // stuff to the lower level pools.
97 for (SSLSocketPoolMap::const_iterator it =
98 ssl_socket_pools_for_proxies_.begin();
99 it != ssl_socket_pools_for_proxies_.end();
100 ++it)
101 it->second->FlushWithError(error);
103 for (HTTPProxySocketPoolMap::const_iterator it =
104 http_proxy_socket_pools_.begin();
105 it != http_proxy_socket_pools_.end();
106 ++it)
107 it->second->FlushWithError(error);
109 for (SSLSocketPoolMap::const_iterator it =
110 ssl_socket_pools_for_https_proxies_.begin();
111 it != ssl_socket_pools_for_https_proxies_.end();
112 ++it)
113 it->second->FlushWithError(error);
115 for (TransportSocketPoolMap::const_iterator it =
116 transport_socket_pools_for_https_proxies_.begin();
117 it != transport_socket_pools_for_https_proxies_.end();
118 ++it)
119 it->second->FlushWithError(error);
121 for (TransportSocketPoolMap::const_iterator it =
122 transport_socket_pools_for_http_proxies_.begin();
123 it != transport_socket_pools_for_http_proxies_.end();
124 ++it)
125 it->second->FlushWithError(error);
127 for (SOCKSSocketPoolMap::const_iterator it =
128 socks_socket_pools_.begin();
129 it != socks_socket_pools_.end();
130 ++it)
131 it->second->FlushWithError(error);
133 for (TransportSocketPoolMap::const_iterator it =
134 transport_socket_pools_for_socks_proxies_.begin();
135 it != transport_socket_pools_for_socks_proxies_.end();
136 ++it)
137 it->second->FlushWithError(error);
139 ssl_socket_pool_->FlushWithError(error);
140 transport_socket_pool_->FlushWithError(error);
143 void ClientSocketPoolManagerImpl::CloseIdleSockets() {
144 // Close sockets in the highest level pools first, since higher level pools'
145 // sockets may release stuff to the lower level pools.
146 for (SSLSocketPoolMap::const_iterator it =
147 ssl_socket_pools_for_proxies_.begin();
148 it != ssl_socket_pools_for_proxies_.end();
149 ++it)
150 it->second->CloseIdleSockets();
152 for (HTTPProxySocketPoolMap::const_iterator it =
153 http_proxy_socket_pools_.begin();
154 it != http_proxy_socket_pools_.end();
155 ++it)
156 it->second->CloseIdleSockets();
158 for (SSLSocketPoolMap::const_iterator it =
159 ssl_socket_pools_for_https_proxies_.begin();
160 it != ssl_socket_pools_for_https_proxies_.end();
161 ++it)
162 it->second->CloseIdleSockets();
164 for (TransportSocketPoolMap::const_iterator it =
165 transport_socket_pools_for_https_proxies_.begin();
166 it != transport_socket_pools_for_https_proxies_.end();
167 ++it)
168 it->second->CloseIdleSockets();
170 for (TransportSocketPoolMap::const_iterator it =
171 transport_socket_pools_for_http_proxies_.begin();
172 it != transport_socket_pools_for_http_proxies_.end();
173 ++it)
174 it->second->CloseIdleSockets();
176 for (SOCKSSocketPoolMap::const_iterator it =
177 socks_socket_pools_.begin();
178 it != socks_socket_pools_.end();
179 ++it)
180 it->second->CloseIdleSockets();
182 for (TransportSocketPoolMap::const_iterator it =
183 transport_socket_pools_for_socks_proxies_.begin();
184 it != transport_socket_pools_for_socks_proxies_.end();
185 ++it)
186 it->second->CloseIdleSockets();
188 ssl_socket_pool_->CloseIdleSockets();
189 transport_socket_pool_->CloseIdleSockets();
192 TransportClientSocketPool*
193 ClientSocketPoolManagerImpl::GetTransportSocketPool() {
194 return transport_socket_pool_.get();
197 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSSLSocketPool() {
198 return ssl_socket_pool_.get();
201 SOCKSClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSOCKSProxy(
202 const HostPortPair& socks_proxy) {
203 SOCKSSocketPoolMap::const_iterator it = socks_socket_pools_.find(socks_proxy);
204 if (it != socks_socket_pools_.end()) {
205 DCHECK(ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
206 return it->second;
209 DCHECK(!ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
211 std::pair<TransportSocketPoolMap::iterator, bool> tcp_ret =
212 transport_socket_pools_for_socks_proxies_.insert(
213 std::make_pair(
214 socks_proxy,
215 new TransportClientSocketPool(
216 max_sockets_per_proxy_server(pool_type_),
217 max_sockets_per_group(pool_type_),
218 &transport_for_socks_pool_histograms_,
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 &socks_pool_histograms_,
230 host_resolver_,
231 tcp_ret.first->second,
232 net_log_)));
234 return ret.first->second;
237 HttpProxyClientSocketPool*
238 ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
239 const HostPortPair& http_proxy) {
240 HTTPProxySocketPoolMap::const_iterator it =
241 http_proxy_socket_pools_.find(http_proxy);
242 if (it != http_proxy_socket_pools_.end()) {
243 DCHECK(ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
244 DCHECK(ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
245 DCHECK(ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
246 return it->second;
249 DCHECK(!ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
250 DCHECK(!ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
251 DCHECK(!ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
253 std::pair<TransportSocketPoolMap::iterator, bool> tcp_http_ret =
254 transport_socket_pools_for_http_proxies_.insert(
255 std::make_pair(
256 http_proxy,
257 new TransportClientSocketPool(
258 max_sockets_per_proxy_server(pool_type_),
259 max_sockets_per_group(pool_type_),
260 &transport_for_http_proxy_pool_histograms_,
261 host_resolver_,
262 socket_factory_,
263 net_log_)));
264 DCHECK(tcp_http_ret.second);
266 std::pair<TransportSocketPoolMap::iterator, bool> tcp_https_ret =
267 transport_socket_pools_for_https_proxies_.insert(
268 std::make_pair(
269 http_proxy,
270 new TransportClientSocketPool(
271 max_sockets_per_proxy_server(pool_type_),
272 max_sockets_per_group(pool_type_),
273 &transport_for_https_proxy_pool_histograms_,
274 host_resolver_,
275 socket_factory_,
276 net_log_)));
277 DCHECK(tcp_https_ret.second);
279 std::pair<SSLSocketPoolMap::iterator, bool> ssl_https_ret =
280 ssl_socket_pools_for_https_proxies_.insert(std::make_pair(
281 http_proxy,
282 new SSLClientSocketPool(max_sockets_per_proxy_server(pool_type_),
283 max_sockets_per_group(pool_type_),
284 &ssl_for_https_proxy_pool_histograms_,
285 host_resolver_,
286 cert_verifier_,
287 server_bound_cert_service_,
288 transport_security_state_,
289 ssl_session_cache_shard_,
290 socket_factory_,
291 tcp_https_ret.first->second /* https proxy */,
292 NULL /* no socks proxy */,
293 NULL /* no http proxy */,
294 ssl_config_service_.get(),
295 net_log_)));
296 DCHECK(tcp_https_ret.second);
298 std::pair<HTTPProxySocketPoolMap::iterator, bool> ret =
299 http_proxy_socket_pools_.insert(
300 std::make_pair(
301 http_proxy,
302 new HttpProxyClientSocketPool(
303 max_sockets_per_proxy_server(pool_type_),
304 max_sockets_per_group(pool_type_),
305 &http_proxy_pool_histograms_,
306 host_resolver_,
307 tcp_http_ret.first->second,
308 ssl_https_ret.first->second,
309 net_log_)));
311 return ret.first->second;
314 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSSLWithProxy(
315 const HostPortPair& proxy_server) {
316 SSLSocketPoolMap::const_iterator it =
317 ssl_socket_pools_for_proxies_.find(proxy_server);
318 if (it != ssl_socket_pools_for_proxies_.end())
319 return it->second;
321 SSLClientSocketPool* new_pool = new SSLClientSocketPool(
322 max_sockets_per_proxy_server(pool_type_),
323 max_sockets_per_group(pool_type_),
324 &ssl_pool_histograms_,
325 host_resolver_,
326 cert_verifier_,
327 server_bound_cert_service_,
328 transport_security_state_,
329 ssl_session_cache_shard_,
330 socket_factory_,
331 NULL, /* no tcp pool, we always go through a proxy */
332 GetSocketPoolForSOCKSProxy(proxy_server),
333 GetSocketPoolForHTTPProxy(proxy_server),
334 ssl_config_service_.get(),
335 net_log_);
337 std::pair<SSLSocketPoolMap::iterator, bool> ret =
338 ssl_socket_pools_for_proxies_.insert(std::make_pair(proxy_server,
339 new_pool));
341 return ret.first->second;
344 base::Value* ClientSocketPoolManagerImpl::SocketPoolInfoToValue() const {
345 base::ListValue* list = new base::ListValue();
346 list->Append(transport_socket_pool_->GetInfoAsValue("transport_socket_pool",
347 "transport_socket_pool",
348 false));
349 // Third parameter is false because |ssl_socket_pool_| uses
350 // |transport_socket_pool_| internally, and do not want to add it a second
351 // time.
352 list->Append(ssl_socket_pool_->GetInfoAsValue("ssl_socket_pool",
353 "ssl_socket_pool",
354 false));
355 AddSocketPoolsToList(list,
356 http_proxy_socket_pools_,
357 "http_proxy_socket_pool",
358 true);
359 AddSocketPoolsToList(list,
360 socks_socket_pools_,
361 "socks_socket_pool",
362 true);
364 // Third parameter is false because |ssl_socket_pools_for_proxies_| use
365 // socket pools in |http_proxy_socket_pools_| and |socks_socket_pools_|.
366 AddSocketPoolsToList(list,
367 ssl_socket_pools_for_proxies_,
368 "ssl_socket_pool_for_proxies",
369 false);
370 return list;
373 void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate* cert) {
374 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
377 void ClientSocketPoolManagerImpl::OnCACertChanged(
378 const X509Certificate* cert) {
379 // We should flush the socket pools if we removed trust from a
380 // cert, because a previously trusted server may have become
381 // untrusted.
383 // We should not flush the socket pools if we added trust to a
384 // cert.
386 // Since the OnCACertChanged method doesn't tell us what
387 // kind of change it is, we have to flush the socket
388 // pools to be safe.
389 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
392 } // namespace net