blob: 5cf98f3cad9e01db60e94337f0a89420cd0f325c [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>
8
[email protected]a42dbd142011-11-17 16:42:029#include "base/logging.h"
10#include "base/values.h"
[email protected]a8af2152012-03-21 20:29:5211#include "net/http/http_network_session.h"
[email protected]536fd0b2013-03-14 17:41:5712#include "net/http/http_proxy_client_socket_pool.h"
[email protected]a42dbd142011-11-17 16:42:0213#include "net/socket/socks_client_socket_pool.h"
14#include "net/socket/ssl_client_socket_pool.h"
15#include "net/socket/transport_client_socket_pool.h"
[email protected]654866142014-06-24 22:53:3116#include "net/socket/websocket_transport_client_socket_pool.h"
[email protected]536fd0b2013-03-14 17:41:5717#include "net/ssl/ssl_config_service.h"
[email protected]a42dbd142011-11-17 16:42:0218
19namespace net {
20
21namespace {
22
23// Appends information about all |socket_pools| to the end of |list|.
24template <class MapType>
[email protected]ea5ef4c2013-06-13 22:50:2725void AddSocketPoolsToList(base::ListValue* list,
[email protected]a42dbd142011-11-17 16:42:0226 const MapType& socket_pools,
27 const std::string& type,
28 bool include_nested_pools) {
29 for (typename MapType::const_iterator it = socket_pools.begin();
30 it != socket_pools.end(); it++) {
31 list->Append(it->second->GetInfoAsValue(it->first.ToString(),
32 type,
33 include_nested_pools));
34 }
35}
36
37} // namespace
38
39ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
40 NetLog* net_log,
41 ClientSocketFactory* socket_factory,
42 HostResolver* host_resolver,
43 CertVerifier* cert_verifier,
[email protected]6b8a3c742014-07-25 00:25:3544 ChannelIDService* channel_id_service,
[email protected]a2a41972011-12-07 17:47:2745 TransportSecurityState* transport_security_state,
[email protected]284303b62013-11-28 15:11:5446 CTVerifier* cert_transparency_verifier,
eranm6571b2b2014-12-03 15:53:2347 CertPolicyEnforcer* cert_policy_enforcer,
[email protected]c3456bb2011-12-12 22:22:1948 const std::string& ssl_session_cache_shard,
[email protected]a8af2152012-03-21 20:29:5249 SSLConfigService* ssl_config_service,
50 HttpNetworkSession::SocketPoolType pool_type)
[email protected]a42dbd142011-11-17 16:42:0251 : net_log_(net_log),
52 socket_factory_(socket_factory),
53 host_resolver_(host_resolver),
54 cert_verifier_(cert_verifier),
[email protected]6b8a3c742014-07-25 00:25:3555 channel_id_service_(channel_id_service),
[email protected]a2a41972011-12-07 17:47:2756 transport_security_state_(transport_security_state),
[email protected]284303b62013-11-28 15:11:5457 cert_transparency_verifier_(cert_transparency_verifier),
eranm6571b2b2014-12-03 15:53:2358 cert_policy_enforcer_(cert_policy_enforcer),
[email protected]c3456bb2011-12-12 22:22:1959 ssl_session_cache_shard_(ssl_session_cache_shard),
[email protected]a42dbd142011-11-17 16:42:0260 ssl_config_service_(ssl_config_service),
[email protected]a8af2152012-03-21 20:29:5261 pool_type_(pool_type),
[email protected]654866142014-06-24 22:53:3162 transport_socket_pool_(
63 pool_type == HttpNetworkSession::WEBSOCKET_SOCKET_POOL
64 ? new WebSocketTransportClientSocketPool(
65 max_sockets_per_pool(pool_type),
66 max_sockets_per_group(pool_type),
[email protected]654866142014-06-24 22:53:3167 host_resolver,
68 socket_factory_,
69 net_log)
70 : new TransportClientSocketPool(max_sockets_per_pool(pool_type),
71 max_sockets_per_group(pool_type),
[email protected]654866142014-06-24 22:53:3172 host_resolver,
73 socket_factory_,
74 net_log)),
[email protected]8e458552014-08-05 00:02:1575 ssl_socket_pool_(new SSLClientSocketPool(max_sockets_per_pool(pool_type),
76 max_sockets_per_group(pool_type),
[email protected]8e458552014-08-05 00:02:1577 cert_verifier,
78 channel_id_service,
79 transport_security_state,
80 cert_transparency_verifier,
eranm6571b2b2014-12-03 15:53:2381 cert_policy_enforcer,
[email protected]8e458552014-08-05 00:02:1582 ssl_session_cache_shard,
83 socket_factory,
84 transport_socket_pool_.get(),
85 NULL /* no socks proxy */,
86 NULL /* no http proxy */,
87 ssl_config_service,
rkaplowd90695c2015-03-25 22:12:4188 net_log)) {
[email protected]7fda9a402012-09-10 14:11:0789 CertDatabase::GetInstance()->AddObserver(this);
[email protected]a42dbd142011-11-17 16:42:0290}
91
92ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() {
[email protected]7fda9a402012-09-10 14:11:0793 CertDatabase::GetInstance()->RemoveObserver(this);
[email protected]a42dbd142011-11-17 16:42:0294}
95
[email protected]7af985a2012-12-14 22:40:4296void ClientSocketPoolManagerImpl::FlushSocketPoolsWithError(int error) {
[email protected]a42dbd142011-11-17 16:42:0297 // Flush the highest level pools first, since higher level pools may release
98 // stuff to the lower level pools.
99
100 for (SSLSocketPoolMap::const_iterator it =
101 ssl_socket_pools_for_proxies_.begin();
102 it != ssl_socket_pools_for_proxies_.end();
103 ++it)
[email protected]7af985a2012-12-14 22:40:42104 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02105
106 for (HTTPProxySocketPoolMap::const_iterator it =
107 http_proxy_socket_pools_.begin();
108 it != http_proxy_socket_pools_.end();
109 ++it)
[email protected]7af985a2012-12-14 22:40:42110 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02111
112 for (SSLSocketPoolMap::const_iterator it =
113 ssl_socket_pools_for_https_proxies_.begin();
114 it != ssl_socket_pools_for_https_proxies_.end();
115 ++it)
[email protected]7af985a2012-12-14 22:40:42116 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02117
118 for (TransportSocketPoolMap::const_iterator it =
119 transport_socket_pools_for_https_proxies_.begin();
120 it != transport_socket_pools_for_https_proxies_.end();
121 ++it)
[email protected]7af985a2012-12-14 22:40:42122 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02123
124 for (TransportSocketPoolMap::const_iterator it =
125 transport_socket_pools_for_http_proxies_.begin();
126 it != transport_socket_pools_for_http_proxies_.end();
127 ++it)
[email protected]7af985a2012-12-14 22:40:42128 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02129
130 for (SOCKSSocketPoolMap::const_iterator it =
131 socks_socket_pools_.begin();
132 it != socks_socket_pools_.end();
133 ++it)
[email protected]7af985a2012-12-14 22:40:42134 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02135
136 for (TransportSocketPoolMap::const_iterator it =
137 transport_socket_pools_for_socks_proxies_.begin();
138 it != transport_socket_pools_for_socks_proxies_.end();
139 ++it)
[email protected]7af985a2012-12-14 22:40:42140 it->second->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02141
[email protected]7af985a2012-12-14 22:40:42142 ssl_socket_pool_->FlushWithError(error);
143 transport_socket_pool_->FlushWithError(error);
[email protected]a42dbd142011-11-17 16:42:02144}
145
146void ClientSocketPoolManagerImpl::CloseIdleSockets() {
147 // Close sockets in the highest level pools first, since higher level pools'
148 // sockets may release stuff to the lower level pools.
149 for (SSLSocketPoolMap::const_iterator it =
150 ssl_socket_pools_for_proxies_.begin();
151 it != ssl_socket_pools_for_proxies_.end();
152 ++it)
153 it->second->CloseIdleSockets();
154
155 for (HTTPProxySocketPoolMap::const_iterator it =
156 http_proxy_socket_pools_.begin();
157 it != http_proxy_socket_pools_.end();
158 ++it)
159 it->second->CloseIdleSockets();
160
161 for (SSLSocketPoolMap::const_iterator it =
162 ssl_socket_pools_for_https_proxies_.begin();
163 it != ssl_socket_pools_for_https_proxies_.end();
164 ++it)
165 it->second->CloseIdleSockets();
166
167 for (TransportSocketPoolMap::const_iterator it =
168 transport_socket_pools_for_https_proxies_.begin();
169 it != transport_socket_pools_for_https_proxies_.end();
170 ++it)
171 it->second->CloseIdleSockets();
172
173 for (TransportSocketPoolMap::const_iterator it =
174 transport_socket_pools_for_http_proxies_.begin();
175 it != transport_socket_pools_for_http_proxies_.end();
176 ++it)
177 it->second->CloseIdleSockets();
178
179 for (SOCKSSocketPoolMap::const_iterator it =
180 socks_socket_pools_.begin();
181 it != socks_socket_pools_.end();
182 ++it)
183 it->second->CloseIdleSockets();
184
185 for (TransportSocketPoolMap::const_iterator it =
186 transport_socket_pools_for_socks_proxies_.begin();
187 it != transport_socket_pools_for_socks_proxies_.end();
188 ++it)
189 it->second->CloseIdleSockets();
190
191 ssl_socket_pool_->CloseIdleSockets();
192 transport_socket_pool_->CloseIdleSockets();
193}
194
195TransportClientSocketPool*
196ClientSocketPoolManagerImpl::GetTransportSocketPool() {
197 return transport_socket_pool_.get();
198}
199
200SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSSLSocketPool() {
201 return ssl_socket_pool_.get();
202}
203
204SOCKSClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSOCKSProxy(
205 const HostPortPair& socks_proxy) {
206 SOCKSSocketPoolMap::const_iterator it = socks_socket_pools_.find(socks_proxy);
207 if (it != socks_socket_pools_.end()) {
208 DCHECK(ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
209 return it->second;
210 }
211
212 DCHECK(!ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
dkelson64cb80d32015-11-11 04:30:45213 int sockets_per_proxy_server = max_sockets_per_proxy_server(pool_type_);
214 int sockets_per_group = std::min(sockets_per_proxy_server,
215 max_sockets_per_group(pool_type_));
[email protected]a42dbd142011-11-17 16:42:02216
217 std::pair<TransportSocketPoolMap::iterator, bool> tcp_ret =
218 transport_socket_pools_for_socks_proxies_.insert(
219 std::make_pair(
220 socks_proxy,
221 new TransportClientSocketPool(
dkelson64cb80d32015-11-11 04:30:45222 sockets_per_proxy_server,
223 sockets_per_group,
[email protected]a42dbd142011-11-17 16:42:02224 host_resolver_,
225 socket_factory_,
226 net_log_)));
227 DCHECK(tcp_ret.second);
228
229 std::pair<SOCKSSocketPoolMap::iterator, bool> ret =
230 socks_socket_pools_.insert(
231 std::make_pair(socks_proxy, new SOCKSClientSocketPool(
dkelson64cb80d32015-11-11 04:30:45232 sockets_per_proxy_server,
233 sockets_per_group,
[email protected]a42dbd142011-11-17 16:42:02234 host_resolver_,
235 tcp_ret.first->second,
236 net_log_)));
237
238 return ret.first->second;
239}
240
241HttpProxyClientSocketPool*
242ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
243 const HostPortPair& http_proxy) {
244 HTTPProxySocketPoolMap::const_iterator it =
245 http_proxy_socket_pools_.find(http_proxy);
246 if (it != http_proxy_socket_pools_.end()) {
247 DCHECK(ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
248 DCHECK(ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
249 DCHECK(ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
250 return it->second;
251 }
252
253 DCHECK(!ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
254 DCHECK(!ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
255 DCHECK(!ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
256
dkelson64cb80d32015-11-11 04:30:45257 int sockets_per_proxy_server = max_sockets_per_proxy_server(pool_type_);
258 int sockets_per_group = std::min(sockets_per_proxy_server,
259 max_sockets_per_group(pool_type_));
260
[email protected]a42dbd142011-11-17 16:42:02261 std::pair<TransportSocketPoolMap::iterator, bool> tcp_http_ret =
262 transport_socket_pools_for_http_proxies_.insert(
263 std::make_pair(
264 http_proxy,
265 new TransportClientSocketPool(
dkelson64cb80d32015-11-11 04:30:45266 sockets_per_proxy_server,
267 sockets_per_group,
[email protected]a42dbd142011-11-17 16:42:02268 host_resolver_,
269 socket_factory_,
270 net_log_)));
271 DCHECK(tcp_http_ret.second);
272
273 std::pair<TransportSocketPoolMap::iterator, bool> tcp_https_ret =
274 transport_socket_pools_for_https_proxies_.insert(
275 std::make_pair(
276 http_proxy,
277 new TransportClientSocketPool(
dkelson64cb80d32015-11-11 04:30:45278 sockets_per_proxy_server,
279 sockets_per_group,
[email protected]a42dbd142011-11-17 16:42:02280 host_resolver_,
281 socket_factory_,
282 net_log_)));
283 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(
hashimotodae13b02015-01-15 04:28:21287 http_proxy, new SSLClientSocketPool(
dkelson64cb80d32015-11-11 04:30:45288 sockets_per_proxy_server,
289 sockets_per_group, cert_verifier_,
hashimotodae13b02015-01-15 04:28:21290 channel_id_service_, transport_security_state_,
291 cert_transparency_verifier_, cert_policy_enforcer_,
292 ssl_session_cache_shard_, socket_factory_,
293 tcp_https_ret.first->second /* https proxy */,
294 NULL /* no socks proxy */, NULL /* no http proxy */,
rsleevif020edc2015-03-16 19:31:24295 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 =
299 http_proxy_socket_pools_.insert(
300 std::make_pair(
301 http_proxy,
302 new HttpProxyClientSocketPool(
dkelson64cb80d32015-11-11 04:30:45303 sockets_per_proxy_server,
304 sockets_per_group,
[email protected]a42dbd142011-11-17 16:42:02305 tcp_http_ret.first->second,
306 ssl_https_ret.first->second,
307 net_log_)));
308
309 return ret.first->second;
310}
311
312SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSSLWithProxy(
313 const HostPortPair& proxy_server) {
314 SSLSocketPoolMap::const_iterator it =
315 ssl_socket_pools_for_proxies_.find(proxy_server);
316 if (it != ssl_socket_pools_for_proxies_.end())
317 return it->second;
318
dkelson64cb80d32015-11-11 04:30:45319 int sockets_per_proxy_server = max_sockets_per_proxy_server(pool_type_);
320 int sockets_per_group = std::min(sockets_per_proxy_server,
321 max_sockets_per_group(pool_type_));
322
[email protected]a42dbd142011-11-17 16:42:02323 SSLClientSocketPool* new_pool = new SSLClientSocketPool(
dkelson64cb80d32015-11-11 04:30:45324 sockets_per_proxy_server,
325 sockets_per_group, cert_verifier_, channel_id_service_,
rkaplowd90695c2015-03-25 22:12:41326 transport_security_state_, cert_transparency_verifier_,
327 cert_policy_enforcer_, ssl_session_cache_shard_, socket_factory_,
[email protected]a42dbd142011-11-17 16:42:02328 NULL, /* no tcp pool, we always go through a proxy */
329 GetSocketPoolForSOCKSProxy(proxy_server),
eranm6571b2b2014-12-03 15:53:23330 GetSocketPoolForHTTPProxy(proxy_server), ssl_config_service_.get(),
rsleevif020edc2015-03-16 19:31:24331 net_log_);
[email protected]a42dbd142011-11-17 16:42:02332
333 std::pair<SSLSocketPoolMap::iterator, bool> ret =
334 ssl_socket_pools_for_proxies_.insert(std::make_pair(proxy_server,
335 new_pool));
336
337 return ret.first->second;
338}
339
payal.pandey62a400292015-05-28 09:29:54340scoped_ptr<base::Value> ClientSocketPoolManagerImpl::SocketPoolInfoToValue()
341 const {
342 scoped_ptr<base::ListValue> list(new base::ListValue());
[email protected]a42dbd142011-11-17 16:42:02343 list->Append(transport_socket_pool_->GetInfoAsValue("transport_socket_pool",
344 "transport_socket_pool",
345 false));
346 // Third parameter is false because |ssl_socket_pool_| uses
347 // |transport_socket_pool_| internally, and do not want to add it a second
348 // time.
349 list->Append(ssl_socket_pool_->GetInfoAsValue("ssl_socket_pool",
350 "ssl_socket_pool",
351 false));
payal.pandey62a400292015-05-28 09:29:54352 AddSocketPoolsToList(list.get(), http_proxy_socket_pools_,
353 "http_proxy_socket_pool", true);
354 AddSocketPoolsToList(list.get(), socks_socket_pools_, "socks_socket_pool",
[email protected]a42dbd142011-11-17 16:42:02355 true);
356
357 // Third parameter is false because |ssl_socket_pools_for_proxies_| use
358 // socket pools in |http_proxy_socket_pools_| and |socks_socket_pools_|.
payal.pandey62a400292015-05-28 09:29:54359 AddSocketPoolsToList(list.get(), ssl_socket_pools_for_proxies_,
360 "ssl_socket_pool_for_proxies", false);
361 return list.Pass();
[email protected]a42dbd142011-11-17 16:42:02362}
363
[email protected]7fda9a402012-09-10 14:11:07364void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate* cert) {
[email protected]7af985a2012-12-14 22:40:42365 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
[email protected]a42dbd142011-11-17 16:42:02366}
367
[email protected]c157b2e22013-10-31 01:38:33368void ClientSocketPoolManagerImpl::OnCACertChanged(
[email protected]a42dbd142011-11-17 16:42:02369 const X509Certificate* cert) {
370 // We should flush the socket pools if we removed trust from a
371 // cert, because a previously trusted server may have become
372 // untrusted.
373 //
374 // We should not flush the socket pools if we added trust to a
375 // cert.
376 //
[email protected]c157b2e22013-10-31 01:38:33377 // Since the OnCACertChanged method doesn't tell us what
378 // kind of change it is, we have to flush the socket
[email protected]a42dbd142011-11-17 16:42:02379 // pools to be safe.
[email protected]7af985a2012-12-14 22:40:42380 FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
[email protected]a42dbd142011-11-17 16:42:02381}
382
383} // namespace net