blob: a701c5966478820bc16a39816ae5879d5c8400cc [file] [log] [blame]
[email protected]9c4eff22012-03-20 22:42:291// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]a42dbd142011-11-17 16:42:022// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/socket/client_socket_pool_manager_impl.h"
6
dkelson64cb80d32015-11-11 04:30:457#include <algorithm>
dchengc7eeda422015-12-26 03:56:488#include <utility>
dkelson64cb80d32015-11-11 04:30:459
[email protected]a42dbd142011-11-17 16:42:0210#include "base/logging.h"
aviadef3442016-10-03 18:50:3911#include "base/memory/ptr_util.h"
[email protected]a42dbd142011-11-17 16:42:0212#include "base/values.h"
[email protected]a8af2152012-03-21 20:29:5213#include "net/http/http_network_session.h"
[email protected]536fd0b2013-03-14 17:41:5714#include "net/http/http_proxy_client_socket_pool.h"
[email protected]a42dbd142011-11-17 16:42:0215#include "net/socket/socks_client_socket_pool.h"
16#include "net/socket/ssl_client_socket_pool.h"
17#include "net/socket/transport_client_socket_pool.h"
[email protected]654866142014-06-24 22:53:3118#include "net/socket/websocket_transport_client_socket_pool.h"
[email protected]536fd0b2013-03-14 17:41:5719#include "net/ssl/ssl_config_service.h"
[email protected]a42dbd142011-11-17 16:42:0220
21namespace net {
22
tbansal7b403bcc2016-04-13 22:33:2123class SocketPerformanceWatcherFactory;
24
[email protected]a42dbd142011-11-17 16:42:0225namespace {
26
27// Appends information about all |socket_pools| to the end of |list|.
28template <class MapType>
[email protected]ea5ef4c2013-06-13 22:50:2729void AddSocketPoolsToList(base::ListValue* list,
[email protected]a42dbd142011-11-17 16:42:0230 const MapType& socket_pools,
31 const std::string& type,
32 bool include_nested_pools) {
33 for (typename MapType::const_iterator it = socket_pools.begin();
34 it != socket_pools.end(); it++) {
35 list->Append(it->second->GetInfoAsValue(it->first.ToString(),
36 type,
37 include_nested_pools));
38 }
39}
40
41} // namespace
42
43ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
44 NetLog* net_log,
45 ClientSocketFactory* socket_factory,
tbansal7b403bcc2016-04-13 22:33:2146 SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
[email protected]a42dbd142011-11-17 16:42:0247 HostResolver* host_resolver,
48 CertVerifier* cert_verifier,
[email protected]6b8a3c742014-07-25 00:25:3549 ChannelIDService* channel_id_service,
[email protected]a2a41972011-12-07 17:47:2750 TransportSecurityState* transport_security_state,
[email protected]284303b62013-11-28 15:11:5451 CTVerifier* cert_transparency_verifier,
estark6f9b3d82016-01-12 21:37:0552 CTPolicyEnforcer* ct_policy_enforcer,
[email protected]c3456bb2011-12-12 22:22:1953 const std::string& ssl_session_cache_shard,
[email protected]a8af2152012-03-21 20:29:5254 SSLConfigService* ssl_config_service,
55 HttpNetworkSession::SocketPoolType pool_type)
[email protected]a42dbd142011-11-17 16:42:0256 : net_log_(net_log),
57 socket_factory_(socket_factory),
tbansal7b403bcc2016-04-13 22:33:2158 socket_performance_watcher_factory_(socket_performance_watcher_factory),
[email protected]a42dbd142011-11-17 16:42:0259 host_resolver_(host_resolver),
60 cert_verifier_(cert_verifier),
[email protected]6b8a3c742014-07-25 00:25:3561 channel_id_service_(channel_id_service),
[email protected]a2a41972011-12-07 17:47:2762 transport_security_state_(transport_security_state),
[email protected]284303b62013-11-28 15:11:5463 cert_transparency_verifier_(cert_transparency_verifier),
estark6f9b3d82016-01-12 21:37:0564 ct_policy_enforcer_(ct_policy_enforcer),
[email protected]c3456bb2011-12-12 22:22:1965 ssl_session_cache_shard_(ssl_session_cache_shard),
[email protected]a42dbd142011-11-17 16:42:0266 ssl_config_service_(ssl_config_service),
[email protected]a8af2152012-03-21 20:29:5267 pool_type_(pool_type),
tbansal7b403bcc2016-04-13 22:33:2168 transport_socket_pool_(pool_type ==
69 HttpNetworkSession::WEBSOCKET_SOCKET_POOL
70 ? new WebSocketTransportClientSocketPool(
71 max_sockets_per_pool(pool_type),
72 max_sockets_per_group(pool_type),
73 host_resolver,
74 socket_factory_,
75 net_log)
76 : new TransportClientSocketPool(
77 max_sockets_per_pool(pool_type),
78 max_sockets_per_group(pool_type),
79 host_resolver,
80 socket_factory_,
81 socket_performance_watcher_factory_,
82 net_log)),
[email protected]8e458552014-08-05 00:02:1583 ssl_socket_pool_(new SSLClientSocketPool(max_sockets_per_pool(pool_type),
84 max_sockets_per_group(pool_type),
[email protected]8e458552014-08-05 00:02:1585 cert_verifier,
86 channel_id_service,
87 transport_security_state,
88 cert_transparency_verifier,
estark6f9b3d82016-01-12 21:37:0589 ct_policy_enforcer,
[email protected]8e458552014-08-05 00:02:1590 ssl_session_cache_shard,
91 socket_factory,
92 transport_socket_pool_.get(),
aviadef3442016-10-03 18:50:3993 nullptr /* no socks proxy */,
94 nullptr /* no http proxy */,
[email protected]8e458552014-08-05 00:02:1595 ssl_config_service,
rkaplowd90695c2015-03-25 22:12:4196 net_log)) {
[email protected]7fda9a402012-09-10 14:11:0797 CertDatabase::GetInstance()->AddObserver(this);
[email protected]a42dbd142011-11-17 16:42:0298}
99
100ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() {
[email protected]7fda9a402012-09-10 14:11:07101 CertDatabase::GetInstance()->RemoveObserver(this);
[email protected]a42dbd142011-11-17 16:42:02102}
103
[email protected]7af985a2012-12-14 22:40:42104void ClientSocketPoolManagerImpl::FlushSocketPoolsWithError(int error) {
[email protected]a42dbd142011-11-17 16:42:02105 // Flush the highest level pools first, since higher level pools may release
106 // stuff to the lower level pools.
107
108 for (SSLSocketPoolMap::const_iterator it =
109 ssl_socket_pools_for_proxies_.begin();
110 it != ssl_socket_pools_for_proxies_.end();
111 ++it)
[email protected]7af985a2012-12-14 22:40:42112 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02113
114 for (HTTPProxySocketPoolMap::const_iterator it =
115 http_proxy_socket_pools_.begin();
116 it != http_proxy_socket_pools_.end();
117 ++it)
[email protected]7af985a2012-12-14 22:40:42118 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02119
120 for (SSLSocketPoolMap::const_iterator it =
121 ssl_socket_pools_for_https_proxies_.begin();
122 it != ssl_socket_pools_for_https_proxies_.end();
123 ++it)
[email protected]7af985a2012-12-14 22:40:42124 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02125
126 for (TransportSocketPoolMap::const_iterator it =
127 transport_socket_pools_for_https_proxies_.begin();
128 it != transport_socket_pools_for_https_proxies_.end();
129 ++it)
[email protected]7af985a2012-12-14 22:40:42130 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02131
132 for (TransportSocketPoolMap::const_iterator it =
133 transport_socket_pools_for_http_proxies_.begin();
134 it != transport_socket_pools_for_http_proxies_.end();
135 ++it)
[email protected]7af985a2012-12-14 22:40:42136 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02137
138 for (SOCKSSocketPoolMap::const_iterator it =
139 socks_socket_pools_.begin();
140 it != socks_socket_pools_.end();
141 ++it)
[email protected]7af985a2012-12-14 22:40:42142 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02143
144 for (TransportSocketPoolMap::const_iterator it =
145 transport_socket_pools_for_socks_proxies_.begin();
146 it != transport_socket_pools_for_socks_proxies_.end();
147 ++it)
[email protected]7af985a2012-12-14 22:40:42148 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02149
[email protected]7af985a2012-12-14 22:40:42150 ssl_socket_pool_->FlushWithError(error);
151 transport_socket_pool_->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02152}
153
154void ClientSocketPoolManagerImpl::CloseIdleSockets() {
155 // Close sockets in the highest level pools first, since higher level pools'
156 // sockets may release stuff to the lower level pools.
157 for (SSLSocketPoolMap::const_iterator it =
158 ssl_socket_pools_for_proxies_.begin();
159 it != ssl_socket_pools_for_proxies_.end();
160 ++it)
161 it->second->CloseIdleSockets();
162
163 for (HTTPProxySocketPoolMap::const_iterator it =
164 http_proxy_socket_pools_.begin();
165 it != http_proxy_socket_pools_.end();
166 ++it)
167 it->second->CloseIdleSockets();
168
169 for (SSLSocketPoolMap::const_iterator it =
170 ssl_socket_pools_for_https_proxies_.begin();
171 it != ssl_socket_pools_for_https_proxies_.end();
172 ++it)
173 it->second->CloseIdleSockets();
174
175 for (TransportSocketPoolMap::const_iterator it =
176 transport_socket_pools_for_https_proxies_.begin();
177 it != transport_socket_pools_for_https_proxies_.end();
178 ++it)
179 it->second->CloseIdleSockets();
180
181 for (TransportSocketPoolMap::const_iterator it =
182 transport_socket_pools_for_http_proxies_.begin();
183 it != transport_socket_pools_for_http_proxies_.end();
184 ++it)
185 it->second->CloseIdleSockets();
186
187 for (SOCKSSocketPoolMap::const_iterator it =
188 socks_socket_pools_.begin();
189 it != socks_socket_pools_.end();
190 ++it)
191 it->second->CloseIdleSockets();
192
193 for (TransportSocketPoolMap::const_iterator it =
194 transport_socket_pools_for_socks_proxies_.begin();
195 it != transport_socket_pools_for_socks_proxies_.end();
196 ++it)
197 it->second->CloseIdleSockets();
198
199 ssl_socket_pool_->CloseIdleSockets();
200 transport_socket_pool_->CloseIdleSockets();
201}
202
203TransportClientSocketPool*
204ClientSocketPoolManagerImpl::GetTransportSocketPool() {
205 return transport_socket_pool_.get();
206}
207
208SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSSLSocketPool() {
209 return ssl_socket_pool_.get();
210}
211
212SOCKSClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSOCKSProxy(
213 const HostPortPair& socks_proxy) {
214 SOCKSSocketPoolMap::const_iterator it = socks_socket_pools_.find(socks_proxy);
215 if (it != socks_socket_pools_.end()) {
skyostilb8f60ca2016-08-12 12:34:43216 DCHECK(base::ContainsKey(transport_socket_pools_for_socks_proxies_,
217 socks_proxy));
aviadef3442016-10-03 18:50:39218 return it->second.get();
[email protected]a42dbd142011-11-17 16:42:02219 }
220
skyostilb8f60ca2016-08-12 12:34:43221 DCHECK(!base::ContainsKey(transport_socket_pools_for_socks_proxies_,
222 socks_proxy));
dkelson64cb80d32015-11-11 04:30:45223 int sockets_per_proxy_server = max_sockets_per_proxy_server(pool_type_);
224 int sockets_per_group = std::min(sockets_per_proxy_server,
225 max_sockets_per_group(pool_type_));
[email protected]a42dbd142011-11-17 16:42:02226
227 std::pair<TransportSocketPoolMap::iterator, bool> tcp_ret =
tbansal7b403bcc2016-04-13 22:33:21228 transport_socket_pools_for_socks_proxies_.insert(std::make_pair(
229 socks_proxy,
aviadef3442016-10-03 18:50:39230 base::MakeUnique<TransportClientSocketPool>(
231 sockets_per_proxy_server, sockets_per_group, host_resolver_,
232 socket_factory_, nullptr, net_log_)));
[email protected]a42dbd142011-11-17 16:42:02233 DCHECK(tcp_ret.second);
234
235 std::pair<SOCKSSocketPoolMap::iterator, bool> ret =
tbansal7b403bcc2016-04-13 22:33:21236 socks_socket_pools_.insert(std::make_pair(
237 socks_proxy,
aviadef3442016-10-03 18:50:39238 base::MakeUnique<SOCKSClientSocketPool>(
239 sockets_per_proxy_server, sockets_per_group, host_resolver_,
240 tcp_ret.first->second.get(), nullptr, net_log_)));
[email protected]a42dbd142011-11-17 16:42:02241
aviadef3442016-10-03 18:50:39242 return ret.first->second.get();
[email protected]a42dbd142011-11-17 16:42:02243}
244
245HttpProxyClientSocketPool*
246ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
247 const HostPortPair& http_proxy) {
248 HTTPProxySocketPoolMap::const_iterator it =
249 http_proxy_socket_pools_.find(http_proxy);
250 if (it != http_proxy_socket_pools_.end()) {
skyostilb8f60ca2016-08-12 12:34:43251 DCHECK(base::ContainsKey(transport_socket_pools_for_http_proxies_,
252 http_proxy));
253 DCHECK(base::ContainsKey(transport_socket_pools_for_https_proxies_,
254 http_proxy));
255 DCHECK(base::ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
aviadef3442016-10-03 18:50:39256 return it->second.get();
[email protected]a42dbd142011-11-17 16:42:02257 }
258
skyostilb8f60ca2016-08-12 12:34:43259 DCHECK(
260 !base::ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
261 DCHECK(!base::ContainsKey(transport_socket_pools_for_https_proxies_,
262 http_proxy));
263 DCHECK(!base::ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
[email protected]a42dbd142011-11-17 16:42:02264
dkelson64cb80d32015-11-11 04:30:45265 int sockets_per_proxy_server = max_sockets_per_proxy_server(pool_type_);
266 int sockets_per_group = std::min(sockets_per_proxy_server,
267 max_sockets_per_group(pool_type_));
268
[email protected]a42dbd142011-11-17 16:42:02269 std::pair<TransportSocketPoolMap::iterator, bool> tcp_http_ret =
tbansal7b403bcc2016-04-13 22:33:21270 transport_socket_pools_for_http_proxies_.insert(std::make_pair(
271 http_proxy,
aviadef3442016-10-03 18:50:39272 base::MakeUnique<TransportClientSocketPool>(
tbansal7b403bcc2016-04-13 22:33:21273 sockets_per_proxy_server, sockets_per_group, host_resolver_,
274 socket_factory_, socket_performance_watcher_factory_, net_log_)));
[email protected]a42dbd142011-11-17 16:42:02275 DCHECK(tcp_http_ret.second);
276
277 std::pair<TransportSocketPoolMap::iterator, bool> tcp_https_ret =
tbansal7b403bcc2016-04-13 22:33:21278 transport_socket_pools_for_https_proxies_.insert(std::make_pair(
279 http_proxy,
aviadef3442016-10-03 18:50:39280 base::MakeUnique<TransportClientSocketPool>(
tbansal7b403bcc2016-04-13 22:33:21281 sockets_per_proxy_server, sockets_per_group, host_resolver_,
282 socket_factory_, socket_performance_watcher_factory_, net_log_)));
[email protected]a42dbd142011-11-17 16:42:02283 DCHECK(tcp_https_ret.second);
284
285 std::pair<SSLSocketPoolMap::iterator, bool> ssl_https_ret =
[email protected]90499482013-06-01 00:39:50286 ssl_socket_pools_for_https_proxies_.insert(std::make_pair(
estark6f9b3d82016-01-12 21:37:05287 http_proxy,
aviadef3442016-10-03 18:50:39288 base::MakeUnique<SSLClientSocketPool>(
estark6f9b3d82016-01-12 21:37:05289 sockets_per_proxy_server, sockets_per_group, cert_verifier_,
290 channel_id_service_, transport_security_state_,
291 cert_transparency_verifier_, ct_policy_enforcer_,
292 ssl_session_cache_shard_, socket_factory_,
aviadef3442016-10-03 18:50:39293 tcp_https_ret.first->second.get() /* https proxy */,
294 nullptr /* no socks proxy */, nullptr /* no http proxy */,
estark6f9b3d82016-01-12 21:37:05295 ssl_config_service_.get(), net_log_)));
[email protected]a42dbd142011-11-17 16:42:02296 DCHECK(tcp_https_ret.second);
297
298 std::pair<HTTPProxySocketPoolMap::iterator, bool> ret =
aviadef3442016-10-03 18:50:39299 http_proxy_socket_pools_.insert(std::make_pair(
300 http_proxy, base::MakeUnique<HttpProxyClientSocketPool>(
301 sockets_per_proxy_server, sockets_per_group,
302 tcp_http_ret.first->second.get(),
303 ssl_https_ret.first->second.get(), net_log_)));
[email protected]a42dbd142011-11-17 16:42:02304
aviadef3442016-10-03 18:50:39305 return ret.first->second.get();
[email protected]a42dbd142011-11-17 16:42:02306}
307
308SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSSLWithProxy(
309 const HostPortPair& proxy_server) {
310 SSLSocketPoolMap::const_iterator it =
311 ssl_socket_pools_for_proxies_.find(proxy_server);
312 if (it != ssl_socket_pools_for_proxies_.end())
aviadef3442016-10-03 18:50:39313 return it->second.get();
[email protected]a42dbd142011-11-17 16:42:02314
dkelson64cb80d32015-11-11 04:30:45315 int sockets_per_proxy_server = max_sockets_per_proxy_server(pool_type_);
316 int sockets_per_group = std::min(sockets_per_proxy_server,
317 max_sockets_per_group(pool_type_));
318
[email protected]a42dbd142011-11-17 16:42:02319 std::pair<SSLSocketPoolMap::iterator, bool> ret =
aviadef3442016-10-03 18:50:39320 ssl_socket_pools_for_proxies_.insert(std::make_pair(
321 proxy_server,
322 base::MakeUnique<SSLClientSocketPool>(
323 sockets_per_proxy_server, sockets_per_group, cert_verifier_,
324 channel_id_service_, transport_security_state_,
325 cert_transparency_verifier_, ct_policy_enforcer_,
326 ssl_session_cache_shard_, socket_factory_,
327 nullptr, /* no tcp pool, we always go through a proxy */
328 GetSocketPoolForSOCKSProxy(proxy_server),
329 GetSocketPoolForHTTPProxy(proxy_server),
330 ssl_config_service_.get(), net_log_)));
[email protected]a42dbd142011-11-17 16:42:02331
aviadef3442016-10-03 18:50:39332 return ret.first->second.get();
[email protected]a42dbd142011-11-17 16:42:02333}
334
danakj655b66c2016-04-16 00:51:38335std::unique_ptr<base::Value>
336ClientSocketPoolManagerImpl::SocketPoolInfoToValue() const {
337 std::unique_ptr<base::ListValue> list(new base::ListValue());
[email protected]a42dbd142011-11-17 16:42:02338 list->Append(transport_socket_pool_->GetInfoAsValue("transport_socket_pool",
339 "transport_socket_pool",
340 false));
341 // Third parameter is false because |ssl_socket_pool_| uses
342 // |transport_socket_pool_| internally, and do not want to add it a second
343 // time.
344 list->Append(ssl_socket_pool_->GetInfoAsValue("ssl_socket_pool",
345 "ssl_socket_pool",
346 false));
payal.pandey62a400292015-05-28 09:29:54347 AddSocketPoolsToList(list.get(), http_proxy_socket_pools_,
348 "http_proxy_socket_pool", true);
349 AddSocketPoolsToList(list.get(), socks_socket_pools_, "socks_socket_pool",
[email protected]a42dbd142011-11-17 16:42:02350 true);
351
352 // Third parameter is false because |ssl_socket_pools_for_proxies_| use
353 // socket pools in |http_proxy_socket_pools_| and |socks_socket_pools_|.
payal.pandey62a400292015-05-28 09:29:54354 AddSocketPoolsToList(list.get(), ssl_socket_pools_for_proxies_,
355 "ssl_socket_pool_for_proxies", false);
dchengc7eeda422015-12-26 03:56:48356 return std::move(list);
[email protected]a42dbd142011-11-17 16:42:02357}
358
[email protected]7fda9a402012-09-10 14:11:07359void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate* cert) {
[email protected]7af985a2012-12-14 22:40:42360 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
[email protected]a42dbd142011-11-17 16:42:02361}
362
[email protected]c157b2e22013-10-31 01:38:33363void ClientSocketPoolManagerImpl::OnCACertChanged(
[email protected]a42dbd142011-11-17 16:42:02364 const X509Certificate* cert) {
365 // We should flush the socket pools if we removed trust from a
366 // cert, because a previously trusted server may have become
367 // untrusted.
368 //
369 // We should not flush the socket pools if we added trust to a
370 // cert.
371 //
[email protected]c157b2e22013-10-31 01:38:33372 // Since the OnCACertChanged method doesn't tell us what
373 // kind of change it is, we have to flush the socket
[email protected]a42dbd142011-11-17 16:42:02374 // pools to be safe.
[email protected]7af985a2012-12-14 22:40:42375 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
[email protected]a42dbd142011-11-17 16:42:02376}
377
378} // namespace net