Roll src/third_party/skia e1a828c:3e3b58d
[chromium-blink-merge.git] / net / socket / client_socket_pool_manager_impl.cc
blob6d0751b3f9bbb00dfa6506ba883ea2e1932b12ed
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 bool enable_ssl_connect_job_waiting,
49 HttpNetworkSession::SocketPoolType pool_type)
50 : net_log_(net_log),
51 socket_factory_(socket_factory),
52 host_resolver_(host_resolver),
53 cert_verifier_(cert_verifier),
54 channel_id_service_(channel_id_service),
55 transport_security_state_(transport_security_state),
56 cert_transparency_verifier_(cert_transparency_verifier),
57 cert_policy_enforcer_(cert_policy_enforcer),
58 ssl_session_cache_shard_(ssl_session_cache_shard),
59 ssl_config_service_(ssl_config_service),
60 enable_ssl_connect_job_waiting_(enable_ssl_connect_job_waiting),
61 pool_type_(pool_type),
62 transport_pool_histograms_("TCP"),
63 transport_socket_pool_(
64 pool_type == HttpNetworkSession::WEBSOCKET_SOCKET_POOL
65 ? new WebSocketTransportClientSocketPool(
66 max_sockets_per_pool(pool_type),
67 max_sockets_per_group(pool_type),
68 &transport_pool_histograms_,
69 host_resolver,
70 socket_factory_,
71 net_log)
72 : new TransportClientSocketPool(max_sockets_per_pool(pool_type),
73 max_sockets_per_group(pool_type),
74 &transport_pool_histograms_,
75 host_resolver,
76 socket_factory_,
77 net_log)),
78 ssl_pool_histograms_("SSL2"),
79 ssl_socket_pool_(new SSLClientSocketPool(max_sockets_per_pool(pool_type),
80 max_sockets_per_group(pool_type),
81 &ssl_pool_histograms_,
82 cert_verifier,
83 channel_id_service,
84 transport_security_state,
85 cert_transparency_verifier,
86 cert_policy_enforcer,
87 ssl_session_cache_shard,
88 socket_factory,
89 transport_socket_pool_.get(),
90 NULL /* no socks proxy */,
91 NULL /* no http proxy */,
92 ssl_config_service,
93 enable_ssl_connect_job_waiting,
94 net_log)),
95 transport_for_socks_pool_histograms_("TCPforSOCKS"),
96 socks_pool_histograms_("SOCK"),
97 transport_for_http_proxy_pool_histograms_("TCPforHTTPProxy"),
98 transport_for_https_proxy_pool_histograms_("TCPforHTTPSProxy"),
99 ssl_for_https_proxy_pool_histograms_("SSLforHTTPSProxy"),
100 http_proxy_pool_histograms_("HTTPProxy"),
101 ssl_socket_pool_for_proxies_histograms_("SSLForProxies") {
102 CertDatabase::GetInstance()->AddObserver(this);
105 ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() {
106 CertDatabase::GetInstance()->RemoveObserver(this);
109 void ClientSocketPoolManagerImpl::FlushSocketPoolsWithError(int error) {
110 // Flush the highest level pools first, since higher level pools may release
111 // stuff to the lower level pools.
113 for (SSLSocketPoolMap::const_iterator it =
114 ssl_socket_pools_for_proxies_.begin();
115 it != ssl_socket_pools_for_proxies_.end();
116 ++it)
117 it->second->FlushWithError(error);
119 for (HTTPProxySocketPoolMap::const_iterator it =
120 http_proxy_socket_pools_.begin();
121 it != http_proxy_socket_pools_.end();
122 ++it)
123 it->second->FlushWithError(error);
125 for (SSLSocketPoolMap::const_iterator it =
126 ssl_socket_pools_for_https_proxies_.begin();
127 it != ssl_socket_pools_for_https_proxies_.end();
128 ++it)
129 it->second->FlushWithError(error);
131 for (TransportSocketPoolMap::const_iterator it =
132 transport_socket_pools_for_https_proxies_.begin();
133 it != transport_socket_pools_for_https_proxies_.end();
134 ++it)
135 it->second->FlushWithError(error);
137 for (TransportSocketPoolMap::const_iterator it =
138 transport_socket_pools_for_http_proxies_.begin();
139 it != transport_socket_pools_for_http_proxies_.end();
140 ++it)
141 it->second->FlushWithError(error);
143 for (SOCKSSocketPoolMap::const_iterator it =
144 socks_socket_pools_.begin();
145 it != socks_socket_pools_.end();
146 ++it)
147 it->second->FlushWithError(error);
149 for (TransportSocketPoolMap::const_iterator it =
150 transport_socket_pools_for_socks_proxies_.begin();
151 it != transport_socket_pools_for_socks_proxies_.end();
152 ++it)
153 it->second->FlushWithError(error);
155 ssl_socket_pool_->FlushWithError(error);
156 transport_socket_pool_->FlushWithError(error);
159 void ClientSocketPoolManagerImpl::CloseIdleSockets() {
160 // Close sockets in the highest level pools first, since higher level pools'
161 // sockets may release stuff to the lower level pools.
162 for (SSLSocketPoolMap::const_iterator it =
163 ssl_socket_pools_for_proxies_.begin();
164 it != ssl_socket_pools_for_proxies_.end();
165 ++it)
166 it->second->CloseIdleSockets();
168 for (HTTPProxySocketPoolMap::const_iterator it =
169 http_proxy_socket_pools_.begin();
170 it != http_proxy_socket_pools_.end();
171 ++it)
172 it->second->CloseIdleSockets();
174 for (SSLSocketPoolMap::const_iterator it =
175 ssl_socket_pools_for_https_proxies_.begin();
176 it != ssl_socket_pools_for_https_proxies_.end();
177 ++it)
178 it->second->CloseIdleSockets();
180 for (TransportSocketPoolMap::const_iterator it =
181 transport_socket_pools_for_https_proxies_.begin();
182 it != transport_socket_pools_for_https_proxies_.end();
183 ++it)
184 it->second->CloseIdleSockets();
186 for (TransportSocketPoolMap::const_iterator it =
187 transport_socket_pools_for_http_proxies_.begin();
188 it != transport_socket_pools_for_http_proxies_.end();
189 ++it)
190 it->second->CloseIdleSockets();
192 for (SOCKSSocketPoolMap::const_iterator it =
193 socks_socket_pools_.begin();
194 it != socks_socket_pools_.end();
195 ++it)
196 it->second->CloseIdleSockets();
198 for (TransportSocketPoolMap::const_iterator it =
199 transport_socket_pools_for_socks_proxies_.begin();
200 it != transport_socket_pools_for_socks_proxies_.end();
201 ++it)
202 it->second->CloseIdleSockets();
204 ssl_socket_pool_->CloseIdleSockets();
205 transport_socket_pool_->CloseIdleSockets();
208 TransportClientSocketPool*
209 ClientSocketPoolManagerImpl::GetTransportSocketPool() {
210 return transport_socket_pool_.get();
213 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSSLSocketPool() {
214 return ssl_socket_pool_.get();
217 SOCKSClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSOCKSProxy(
218 const HostPortPair& socks_proxy) {
219 SOCKSSocketPoolMap::const_iterator it = socks_socket_pools_.find(socks_proxy);
220 if (it != socks_socket_pools_.end()) {
221 DCHECK(ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
222 return it->second;
225 DCHECK(!ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
227 std::pair<TransportSocketPoolMap::iterator, bool> tcp_ret =
228 transport_socket_pools_for_socks_proxies_.insert(
229 std::make_pair(
230 socks_proxy,
231 new TransportClientSocketPool(
232 max_sockets_per_proxy_server(pool_type_),
233 max_sockets_per_group(pool_type_),
234 &transport_for_socks_pool_histograms_,
235 host_resolver_,
236 socket_factory_,
237 net_log_)));
238 DCHECK(tcp_ret.second);
240 std::pair<SOCKSSocketPoolMap::iterator, bool> ret =
241 socks_socket_pools_.insert(
242 std::make_pair(socks_proxy, new SOCKSClientSocketPool(
243 max_sockets_per_proxy_server(pool_type_),
244 max_sockets_per_group(pool_type_),
245 &socks_pool_histograms_,
246 host_resolver_,
247 tcp_ret.first->second,
248 net_log_)));
250 return ret.first->second;
253 HttpProxyClientSocketPool*
254 ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
255 const HostPortPair& http_proxy) {
256 HTTPProxySocketPoolMap::const_iterator it =
257 http_proxy_socket_pools_.find(http_proxy);
258 if (it != http_proxy_socket_pools_.end()) {
259 DCHECK(ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
260 DCHECK(ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
261 DCHECK(ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
262 return it->second;
265 DCHECK(!ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
266 DCHECK(!ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
267 DCHECK(!ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
269 std::pair<TransportSocketPoolMap::iterator, bool> tcp_http_ret =
270 transport_socket_pools_for_http_proxies_.insert(
271 std::make_pair(
272 http_proxy,
273 new TransportClientSocketPool(
274 max_sockets_per_proxy_server(pool_type_),
275 max_sockets_per_group(pool_type_),
276 &transport_for_http_proxy_pool_histograms_,
277 host_resolver_,
278 socket_factory_,
279 net_log_)));
280 DCHECK(tcp_http_ret.second);
282 std::pair<TransportSocketPoolMap::iterator, bool> tcp_https_ret =
283 transport_socket_pools_for_https_proxies_.insert(
284 std::make_pair(
285 http_proxy,
286 new TransportClientSocketPool(
287 max_sockets_per_proxy_server(pool_type_),
288 max_sockets_per_group(pool_type_),
289 &transport_for_https_proxy_pool_histograms_,
290 host_resolver_,
291 socket_factory_,
292 net_log_)));
293 DCHECK(tcp_https_ret.second);
295 std::pair<SSLSocketPoolMap::iterator, bool> ssl_https_ret =
296 ssl_socket_pools_for_https_proxies_.insert(std::make_pair(
297 http_proxy, new SSLClientSocketPool(
298 max_sockets_per_proxy_server(pool_type_),
299 max_sockets_per_group(pool_type_),
300 &ssl_for_https_proxy_pool_histograms_, cert_verifier_,
301 channel_id_service_, transport_security_state_,
302 cert_transparency_verifier_, cert_policy_enforcer_,
303 ssl_session_cache_shard_, socket_factory_,
304 tcp_https_ret.first->second /* https proxy */,
305 NULL /* no socks proxy */, NULL /* no http proxy */,
306 ssl_config_service_.get(),
307 enable_ssl_connect_job_waiting_, net_log_)));
308 DCHECK(tcp_https_ret.second);
310 std::pair<HTTPProxySocketPoolMap::iterator, bool> ret =
311 http_proxy_socket_pools_.insert(
312 std::make_pair(
313 http_proxy,
314 new HttpProxyClientSocketPool(
315 max_sockets_per_proxy_server(pool_type_),
316 max_sockets_per_group(pool_type_),
317 &http_proxy_pool_histograms_,
318 tcp_http_ret.first->second,
319 ssl_https_ret.first->second,
320 net_log_)));
322 return ret.first->second;
325 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSSLWithProxy(
326 const HostPortPair& proxy_server) {
327 SSLSocketPoolMap::const_iterator it =
328 ssl_socket_pools_for_proxies_.find(proxy_server);
329 if (it != ssl_socket_pools_for_proxies_.end())
330 return it->second;
332 SSLClientSocketPool* new_pool = new SSLClientSocketPool(
333 max_sockets_per_proxy_server(pool_type_),
334 max_sockets_per_group(pool_type_), &ssl_pool_histograms_, cert_verifier_,
335 channel_id_service_, transport_security_state_,
336 cert_transparency_verifier_, cert_policy_enforcer_,
337 ssl_session_cache_shard_, socket_factory_,
338 NULL, /* no tcp pool, we always go through a proxy */
339 GetSocketPoolForSOCKSProxy(proxy_server),
340 GetSocketPoolForHTTPProxy(proxy_server), ssl_config_service_.get(),
341 enable_ssl_connect_job_waiting_, net_log_);
343 std::pair<SSLSocketPoolMap::iterator, bool> ret =
344 ssl_socket_pools_for_proxies_.insert(std::make_pair(proxy_server,
345 new_pool));
347 return ret.first->second;
350 base::Value* ClientSocketPoolManagerImpl::SocketPoolInfoToValue() const {
351 base::ListValue* list = new base::ListValue();
352 list->Append(transport_socket_pool_->GetInfoAsValue("transport_socket_pool",
353 "transport_socket_pool",
354 false));
355 // Third parameter is false because |ssl_socket_pool_| uses
356 // |transport_socket_pool_| internally, and do not want to add it a second
357 // time.
358 list->Append(ssl_socket_pool_->GetInfoAsValue("ssl_socket_pool",
359 "ssl_socket_pool",
360 false));
361 AddSocketPoolsToList(list,
362 http_proxy_socket_pools_,
363 "http_proxy_socket_pool",
364 true);
365 AddSocketPoolsToList(list,
366 socks_socket_pools_,
367 "socks_socket_pool",
368 true);
370 // Third parameter is false because |ssl_socket_pools_for_proxies_| use
371 // socket pools in |http_proxy_socket_pools_| and |socks_socket_pools_|.
372 AddSocketPoolsToList(list,
373 ssl_socket_pools_for_proxies_,
374 "ssl_socket_pool_for_proxies",
375 false);
376 return list;
379 void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate* cert) {
380 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
383 void ClientSocketPoolManagerImpl::OnCACertChanged(
384 const X509Certificate* cert) {
385 // We should flush the socket pools if we removed trust from a
386 // cert, because a previously trusted server may have become
387 // untrusted.
389 // We should not flush the socket pools if we added trust to a
390 // cert.
392 // Since the OnCACertChanged method doesn't tell us what
393 // kind of change it is, we have to flush the socket
394 // pools to be safe.
395 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
398 } // namespace net