Show Pages in chrome://md-settings
[chromium-blink-merge.git] / net / socket / client_socket_pool_manager_impl.cc
blob34599aa484c82fae1460397af39c115973a5cd9a
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_pool_histograms_("TCP"),
61 transport_socket_pool_(
62 pool_type == HttpNetworkSession::WEBSOCKET_SOCKET_POOL
63 ? new WebSocketTransportClientSocketPool(
64 max_sockets_per_pool(pool_type),
65 max_sockets_per_group(pool_type),
66 &transport_pool_histograms_,
67 host_resolver,
68 socket_factory_,
69 net_log)
70 : new TransportClientSocketPool(max_sockets_per_pool(pool_type),
71 max_sockets_per_group(pool_type),
72 &transport_pool_histograms_,
73 host_resolver,
74 socket_factory_,
75 net_log)),
76 ssl_pool_histograms_("SSL2"),
77 ssl_socket_pool_(new SSLClientSocketPool(max_sockets_per_pool(pool_type),
78 max_sockets_per_group(pool_type),
79 &ssl_pool_histograms_,
80 cert_verifier,
81 channel_id_service,
82 transport_security_state,
83 cert_transparency_verifier,
84 cert_policy_enforcer,
85 ssl_session_cache_shard,
86 socket_factory,
87 transport_socket_pool_.get(),
88 NULL /* no socks proxy */,
89 NULL /* no http proxy */,
90 ssl_config_service,
91 net_log)),
92 transport_for_socks_pool_histograms_("TCPforSOCKS"),
93 socks_pool_histograms_("SOCK"),
94 transport_for_http_proxy_pool_histograms_("TCPforHTTPProxy"),
95 transport_for_https_proxy_pool_histograms_("TCPforHTTPSProxy"),
96 ssl_for_https_proxy_pool_histograms_("SSLforHTTPSProxy"),
97 http_proxy_pool_histograms_("HTTPProxy"),
98 ssl_socket_pool_for_proxies_histograms_("SSLForProxies") {
99 CertDatabase::GetInstance()->AddObserver(this);
102 ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() {
103 CertDatabase::GetInstance()->RemoveObserver(this);
106 void ClientSocketPoolManagerImpl::FlushSocketPoolsWithError(int error) {
107 // Flush the highest level pools first, since higher level pools may release
108 // stuff to the lower level pools.
110 for (SSLSocketPoolMap::const_iterator it =
111 ssl_socket_pools_for_proxies_.begin();
112 it != ssl_socket_pools_for_proxies_.end();
113 ++it)
114 it->second->FlushWithError(error);
116 for (HTTPProxySocketPoolMap::const_iterator it =
117 http_proxy_socket_pools_.begin();
118 it != http_proxy_socket_pools_.end();
119 ++it)
120 it->second->FlushWithError(error);
122 for (SSLSocketPoolMap::const_iterator it =
123 ssl_socket_pools_for_https_proxies_.begin();
124 it != ssl_socket_pools_for_https_proxies_.end();
125 ++it)
126 it->second->FlushWithError(error);
128 for (TransportSocketPoolMap::const_iterator it =
129 transport_socket_pools_for_https_proxies_.begin();
130 it != transport_socket_pools_for_https_proxies_.end();
131 ++it)
132 it->second->FlushWithError(error);
134 for (TransportSocketPoolMap::const_iterator it =
135 transport_socket_pools_for_http_proxies_.begin();
136 it != transport_socket_pools_for_http_proxies_.end();
137 ++it)
138 it->second->FlushWithError(error);
140 for (SOCKSSocketPoolMap::const_iterator it =
141 socks_socket_pools_.begin();
142 it != socks_socket_pools_.end();
143 ++it)
144 it->second->FlushWithError(error);
146 for (TransportSocketPoolMap::const_iterator it =
147 transport_socket_pools_for_socks_proxies_.begin();
148 it != transport_socket_pools_for_socks_proxies_.end();
149 ++it)
150 it->second->FlushWithError(error);
152 ssl_socket_pool_->FlushWithError(error);
153 transport_socket_pool_->FlushWithError(error);
156 void ClientSocketPoolManagerImpl::CloseIdleSockets() {
157 // Close sockets in the highest level pools first, since higher level pools'
158 // sockets may release stuff to the lower level pools.
159 for (SSLSocketPoolMap::const_iterator it =
160 ssl_socket_pools_for_proxies_.begin();
161 it != ssl_socket_pools_for_proxies_.end();
162 ++it)
163 it->second->CloseIdleSockets();
165 for (HTTPProxySocketPoolMap::const_iterator it =
166 http_proxy_socket_pools_.begin();
167 it != http_proxy_socket_pools_.end();
168 ++it)
169 it->second->CloseIdleSockets();
171 for (SSLSocketPoolMap::const_iterator it =
172 ssl_socket_pools_for_https_proxies_.begin();
173 it != ssl_socket_pools_for_https_proxies_.end();
174 ++it)
175 it->second->CloseIdleSockets();
177 for (TransportSocketPoolMap::const_iterator it =
178 transport_socket_pools_for_https_proxies_.begin();
179 it != transport_socket_pools_for_https_proxies_.end();
180 ++it)
181 it->second->CloseIdleSockets();
183 for (TransportSocketPoolMap::const_iterator it =
184 transport_socket_pools_for_http_proxies_.begin();
185 it != transport_socket_pools_for_http_proxies_.end();
186 ++it)
187 it->second->CloseIdleSockets();
189 for (SOCKSSocketPoolMap::const_iterator it =
190 socks_socket_pools_.begin();
191 it != socks_socket_pools_.end();
192 ++it)
193 it->second->CloseIdleSockets();
195 for (TransportSocketPoolMap::const_iterator it =
196 transport_socket_pools_for_socks_proxies_.begin();
197 it != transport_socket_pools_for_socks_proxies_.end();
198 ++it)
199 it->second->CloseIdleSockets();
201 ssl_socket_pool_->CloseIdleSockets();
202 transport_socket_pool_->CloseIdleSockets();
205 TransportClientSocketPool*
206 ClientSocketPoolManagerImpl::GetTransportSocketPool() {
207 return transport_socket_pool_.get();
210 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSSLSocketPool() {
211 return ssl_socket_pool_.get();
214 SOCKSClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSOCKSProxy(
215 const HostPortPair& socks_proxy) {
216 SOCKSSocketPoolMap::const_iterator it = socks_socket_pools_.find(socks_proxy);
217 if (it != socks_socket_pools_.end()) {
218 DCHECK(ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
219 return it->second;
222 DCHECK(!ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
224 std::pair<TransportSocketPoolMap::iterator, bool> tcp_ret =
225 transport_socket_pools_for_socks_proxies_.insert(
226 std::make_pair(
227 socks_proxy,
228 new TransportClientSocketPool(
229 max_sockets_per_proxy_server(pool_type_),
230 max_sockets_per_group(pool_type_),
231 &transport_for_socks_pool_histograms_,
232 host_resolver_,
233 socket_factory_,
234 net_log_)));
235 DCHECK(tcp_ret.second);
237 std::pair<SOCKSSocketPoolMap::iterator, bool> ret =
238 socks_socket_pools_.insert(
239 std::make_pair(socks_proxy, new SOCKSClientSocketPool(
240 max_sockets_per_proxy_server(pool_type_),
241 max_sockets_per_group(pool_type_),
242 &socks_pool_histograms_,
243 host_resolver_,
244 tcp_ret.first->second,
245 net_log_)));
247 return ret.first->second;
250 HttpProxyClientSocketPool*
251 ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
252 const HostPortPair& http_proxy) {
253 HTTPProxySocketPoolMap::const_iterator it =
254 http_proxy_socket_pools_.find(http_proxy);
255 if (it != http_proxy_socket_pools_.end()) {
256 DCHECK(ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
257 DCHECK(ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
258 DCHECK(ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
259 return it->second;
262 DCHECK(!ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
263 DCHECK(!ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
264 DCHECK(!ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
266 std::pair<TransportSocketPoolMap::iterator, bool> tcp_http_ret =
267 transport_socket_pools_for_http_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_http_proxy_pool_histograms_,
274 host_resolver_,
275 socket_factory_,
276 net_log_)));
277 DCHECK(tcp_http_ret.second);
279 std::pair<TransportSocketPoolMap::iterator, bool> tcp_https_ret =
280 transport_socket_pools_for_https_proxies_.insert(
281 std::make_pair(
282 http_proxy,
283 new TransportClientSocketPool(
284 max_sockets_per_proxy_server(pool_type_),
285 max_sockets_per_group(pool_type_),
286 &transport_for_https_proxy_pool_histograms_,
287 host_resolver_,
288 socket_factory_,
289 net_log_)));
290 DCHECK(tcp_https_ret.second);
292 std::pair<SSLSocketPoolMap::iterator, bool> ssl_https_ret =
293 ssl_socket_pools_for_https_proxies_.insert(std::make_pair(
294 http_proxy, new SSLClientSocketPool(
295 max_sockets_per_proxy_server(pool_type_),
296 max_sockets_per_group(pool_type_),
297 &ssl_for_https_proxy_pool_histograms_, cert_verifier_,
298 channel_id_service_, transport_security_state_,
299 cert_transparency_verifier_, cert_policy_enforcer_,
300 ssl_session_cache_shard_, socket_factory_,
301 tcp_https_ret.first->second /* https proxy */,
302 NULL /* no socks proxy */, NULL /* no http proxy */,
303 ssl_config_service_.get(), net_log_)));
304 DCHECK(tcp_https_ret.second);
306 std::pair<HTTPProxySocketPoolMap::iterator, bool> ret =
307 http_proxy_socket_pools_.insert(
308 std::make_pair(
309 http_proxy,
310 new HttpProxyClientSocketPool(
311 max_sockets_per_proxy_server(pool_type_),
312 max_sockets_per_group(pool_type_),
313 &http_proxy_pool_histograms_,
314 tcp_http_ret.first->second,
315 ssl_https_ret.first->second,
316 net_log_)));
318 return ret.first->second;
321 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSSLWithProxy(
322 const HostPortPair& proxy_server) {
323 SSLSocketPoolMap::const_iterator it =
324 ssl_socket_pools_for_proxies_.find(proxy_server);
325 if (it != ssl_socket_pools_for_proxies_.end())
326 return it->second;
328 SSLClientSocketPool* new_pool = new SSLClientSocketPool(
329 max_sockets_per_proxy_server(pool_type_),
330 max_sockets_per_group(pool_type_), &ssl_pool_histograms_, cert_verifier_,
331 channel_id_service_, transport_security_state_,
332 cert_transparency_verifier_, cert_policy_enforcer_,
333 ssl_session_cache_shard_, socket_factory_,
334 NULL, /* no tcp pool, we always go through a proxy */
335 GetSocketPoolForSOCKSProxy(proxy_server),
336 GetSocketPoolForHTTPProxy(proxy_server), ssl_config_service_.get(),
337 net_log_);
339 std::pair<SSLSocketPoolMap::iterator, bool> ret =
340 ssl_socket_pools_for_proxies_.insert(std::make_pair(proxy_server,
341 new_pool));
343 return ret.first->second;
346 base::Value* ClientSocketPoolManagerImpl::SocketPoolInfoToValue() const {
347 base::ListValue* list = new base::ListValue();
348 list->Append(transport_socket_pool_->GetInfoAsValue("transport_socket_pool",
349 "transport_socket_pool",
350 false));
351 // Third parameter is false because |ssl_socket_pool_| uses
352 // |transport_socket_pool_| internally, and do not want to add it a second
353 // time.
354 list->Append(ssl_socket_pool_->GetInfoAsValue("ssl_socket_pool",
355 "ssl_socket_pool",
356 false));
357 AddSocketPoolsToList(list,
358 http_proxy_socket_pools_,
359 "http_proxy_socket_pool",
360 true);
361 AddSocketPoolsToList(list,
362 socks_socket_pools_,
363 "socks_socket_pool",
364 true);
366 // Third parameter is false because |ssl_socket_pools_for_proxies_| use
367 // socket pools in |http_proxy_socket_pools_| and |socks_socket_pools_|.
368 AddSocketPoolsToList(list,
369 ssl_socket_pools_for_proxies_,
370 "ssl_socket_pool_for_proxies",
371 false);
372 return list;
375 void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate* cert) {
376 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
379 void ClientSocketPoolManagerImpl::OnCACertChanged(
380 const X509Certificate* cert) {
381 // We should flush the socket pools if we removed trust from a
382 // cert, because a previously trusted server may have become
383 // untrusted.
385 // We should not flush the socket pools if we added trust to a
386 // cert.
388 // Since the OnCACertChanged method doesn't tell us what
389 // kind of change it is, we have to flush the socket
390 // pools to be safe.
391 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
394 } // namespace net