| Index: net/socket/client_socket_pool_manager_impl.cc
|
| diff --git a/net/socket/client_socket_pool_manager_impl.cc b/net/socket/client_socket_pool_manager_impl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3626ec7ff525202574e345a9d5a6ca2063c6a81e
|
| --- /dev/null
|
| +++ b/net/socket/client_socket_pool_manager_impl.cc
|
| @@ -0,0 +1,394 @@
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "net/socket/client_socket_pool_manager_impl.h"
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/values.h"
|
| +#include "net/base/ssl_config_service.h"
|
| +#include "net/http/http_proxy_client_socket_pool.h"
|
| +#include "net/socket/socks_client_socket_pool.h"
|
| +#include "net/socket/ssl_client_socket_pool.h"
|
| +#include "net/socket/transport_client_socket_pool.h"
|
| +
|
| +namespace net {
|
| +
|
| +namespace {
|
| +
|
| +// Appends information about all |socket_pools| to the end of |list|.
|
| +template <class MapType>
|
| +void AddSocketPoolsToList(ListValue* list,
|
| + const MapType& socket_pools,
|
| + const std::string& type,
|
| + bool include_nested_pools) {
|
| + for (typename MapType::const_iterator it = socket_pools.begin();
|
| + it != socket_pools.end(); it++) {
|
| + list->Append(it->second->GetInfoAsValue(it->first.ToString(),
|
| + type,
|
| + include_nested_pools));
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
|
| + NetLog* net_log,
|
| + ClientSocketFactory* socket_factory,
|
| + HostResolver* host_resolver,
|
| + CertVerifier* cert_verifier,
|
| + OriginBoundCertService* origin_bound_cert_service,
|
| + DnsRRResolver* dnsrr_resolver,
|
| + DnsCertProvenanceChecker* dns_cert_checker,
|
| + SSLHostInfoFactory* ssl_host_info_factory,
|
| + ProxyService* proxy_service,
|
| + SSLConfigService* ssl_config_service)
|
| + : net_log_(net_log),
|
| + socket_factory_(socket_factory),
|
| + host_resolver_(host_resolver),
|
| + cert_verifier_(cert_verifier),
|
| + origin_bound_cert_service_(origin_bound_cert_service),
|
| + dnsrr_resolver_(dnsrr_resolver),
|
| + dns_cert_checker_(dns_cert_checker),
|
| + ssl_host_info_factory_(ssl_host_info_factory),
|
| + proxy_service_(proxy_service),
|
| + ssl_config_service_(ssl_config_service),
|
| + transport_pool_histograms_("TCP"),
|
| + transport_socket_pool_(new TransportClientSocketPool(
|
| + max_sockets_per_pool(), max_sockets_per_group(),
|
| + &transport_pool_histograms_,
|
| + host_resolver,
|
| + socket_factory_,
|
| + net_log)),
|
| + ssl_pool_histograms_("SSL2"),
|
| + ssl_socket_pool_(new SSLClientSocketPool(
|
| + max_sockets_per_pool(), max_sockets_per_group(),
|
| + &ssl_pool_histograms_,
|
| + host_resolver,
|
| + cert_verifier,
|
| + origin_bound_cert_service,
|
| + dnsrr_resolver,
|
| + dns_cert_checker,
|
| + ssl_host_info_factory,
|
| + socket_factory,
|
| + transport_socket_pool_.get(),
|
| + NULL /* no socks proxy */,
|
| + NULL /* no http proxy */,
|
| + ssl_config_service,
|
| + net_log)),
|
| + transport_for_socks_pool_histograms_("TCPforSOCKS"),
|
| + socks_pool_histograms_("SOCK"),
|
| + transport_for_http_proxy_pool_histograms_("TCPforHTTPProxy"),
|
| + transport_for_https_proxy_pool_histograms_("TCPforHTTPSProxy"),
|
| + ssl_for_https_proxy_pool_histograms_("SSLforHTTPSProxy"),
|
| + http_proxy_pool_histograms_("HTTPProxy"),
|
| + ssl_socket_pool_for_proxies_histograms_("SSLForProxies") {
|
| + CertDatabase::AddObserver(this);
|
| +}
|
| +
|
| +ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() {
|
| + CertDatabase::RemoveObserver(this);
|
| +}
|
| +
|
| +void ClientSocketPoolManagerImpl::FlushSocketPools() {
|
| + // Flush the highest level pools first, since higher level pools may release
|
| + // stuff to the lower level pools.
|
| +
|
| + for (SSLSocketPoolMap::const_iterator it =
|
| + ssl_socket_pools_for_proxies_.begin();
|
| + it != ssl_socket_pools_for_proxies_.end();
|
| + ++it)
|
| + it->second->Flush();
|
| +
|
| + for (HTTPProxySocketPoolMap::const_iterator it =
|
| + http_proxy_socket_pools_.begin();
|
| + it != http_proxy_socket_pools_.end();
|
| + ++it)
|
| + it->second->Flush();
|
| +
|
| + for (SSLSocketPoolMap::const_iterator it =
|
| + ssl_socket_pools_for_https_proxies_.begin();
|
| + it != ssl_socket_pools_for_https_proxies_.end();
|
| + ++it)
|
| + it->second->Flush();
|
| +
|
| + for (TransportSocketPoolMap::const_iterator it =
|
| + transport_socket_pools_for_https_proxies_.begin();
|
| + it != transport_socket_pools_for_https_proxies_.end();
|
| + ++it)
|
| + it->second->Flush();
|
| +
|
| + for (TransportSocketPoolMap::const_iterator it =
|
| + transport_socket_pools_for_http_proxies_.begin();
|
| + it != transport_socket_pools_for_http_proxies_.end();
|
| + ++it)
|
| + it->second->Flush();
|
| +
|
| + for (SOCKSSocketPoolMap::const_iterator it =
|
| + socks_socket_pools_.begin();
|
| + it != socks_socket_pools_.end();
|
| + ++it)
|
| + it->second->Flush();
|
| +
|
| + for (TransportSocketPoolMap::const_iterator it =
|
| + transport_socket_pools_for_socks_proxies_.begin();
|
| + it != transport_socket_pools_for_socks_proxies_.end();
|
| + ++it)
|
| + it->second->Flush();
|
| +
|
| + ssl_socket_pool_->Flush();
|
| + transport_socket_pool_->Flush();
|
| +}
|
| +
|
| +void ClientSocketPoolManagerImpl::CloseIdleSockets() {
|
| + // Close sockets in the highest level pools first, since higher level pools'
|
| + // sockets may release stuff to the lower level pools.
|
| + for (SSLSocketPoolMap::const_iterator it =
|
| + ssl_socket_pools_for_proxies_.begin();
|
| + it != ssl_socket_pools_for_proxies_.end();
|
| + ++it)
|
| + it->second->CloseIdleSockets();
|
| +
|
| + for (HTTPProxySocketPoolMap::const_iterator it =
|
| + http_proxy_socket_pools_.begin();
|
| + it != http_proxy_socket_pools_.end();
|
| + ++it)
|
| + it->second->CloseIdleSockets();
|
| +
|
| + for (SSLSocketPoolMap::const_iterator it =
|
| + ssl_socket_pools_for_https_proxies_.begin();
|
| + it != ssl_socket_pools_for_https_proxies_.end();
|
| + ++it)
|
| + it->second->CloseIdleSockets();
|
| +
|
| + for (TransportSocketPoolMap::const_iterator it =
|
| + transport_socket_pools_for_https_proxies_.begin();
|
| + it != transport_socket_pools_for_https_proxies_.end();
|
| + ++it)
|
| + it->second->CloseIdleSockets();
|
| +
|
| + for (TransportSocketPoolMap::const_iterator it =
|
| + transport_socket_pools_for_http_proxies_.begin();
|
| + it != transport_socket_pools_for_http_proxies_.end();
|
| + ++it)
|
| + it->second->CloseIdleSockets();
|
| +
|
| + for (SOCKSSocketPoolMap::const_iterator it =
|
| + socks_socket_pools_.begin();
|
| + it != socks_socket_pools_.end();
|
| + ++it)
|
| + it->second->CloseIdleSockets();
|
| +
|
| + for (TransportSocketPoolMap::const_iterator it =
|
| + transport_socket_pools_for_socks_proxies_.begin();
|
| + it != transport_socket_pools_for_socks_proxies_.end();
|
| + ++it)
|
| + it->second->CloseIdleSockets();
|
| +
|
| + ssl_socket_pool_->CloseIdleSockets();
|
| + transport_socket_pool_->CloseIdleSockets();
|
| +}
|
| +
|
| +TransportClientSocketPool*
|
| +ClientSocketPoolManagerImpl::GetTransportSocketPool() {
|
| + return transport_socket_pool_.get();
|
| +}
|
| +
|
| +SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSSLSocketPool() {
|
| + return ssl_socket_pool_.get();
|
| +}
|
| +
|
| +SOCKSClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSOCKSProxy(
|
| + const HostPortPair& socks_proxy) {
|
| + SOCKSSocketPoolMap::const_iterator it = socks_socket_pools_.find(socks_proxy);
|
| + if (it != socks_socket_pools_.end()) {
|
| + DCHECK(ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
|
| + return it->second;
|
| + }
|
| +
|
| + DCHECK(!ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
|
| +
|
| + std::pair<TransportSocketPoolMap::iterator, bool> tcp_ret =
|
| + transport_socket_pools_for_socks_proxies_.insert(
|
| + std::make_pair(
|
| + socks_proxy,
|
| + new TransportClientSocketPool(
|
| + max_sockets_per_proxy_server(),
|
| + max_sockets_per_group(),
|
| + &transport_for_socks_pool_histograms_,
|
| + host_resolver_,
|
| + socket_factory_,
|
| + net_log_)));
|
| + DCHECK(tcp_ret.second);
|
| +
|
| + std::pair<SOCKSSocketPoolMap::iterator, bool> ret =
|
| + socks_socket_pools_.insert(
|
| + std::make_pair(socks_proxy, new SOCKSClientSocketPool(
|
| + max_sockets_per_proxy_server(),
|
| + max_sockets_per_group(),
|
| + &socks_pool_histograms_,
|
| + host_resolver_,
|
| + tcp_ret.first->second,
|
| + net_log_)));
|
| +
|
| + return ret.first->second;
|
| +}
|
| +
|
| +HttpProxyClientSocketPool*
|
| +ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
|
| + const HostPortPair& http_proxy) {
|
| + HTTPProxySocketPoolMap::const_iterator it =
|
| + http_proxy_socket_pools_.find(http_proxy);
|
| + if (it != http_proxy_socket_pools_.end()) {
|
| + DCHECK(ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
|
| + DCHECK(ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
|
| + DCHECK(ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
|
| + return it->second;
|
| + }
|
| +
|
| + DCHECK(!ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
|
| + DCHECK(!ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
|
| + DCHECK(!ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
|
| +
|
| + std::pair<TransportSocketPoolMap::iterator, bool> tcp_http_ret =
|
| + transport_socket_pools_for_http_proxies_.insert(
|
| + std::make_pair(
|
| + http_proxy,
|
| + new TransportClientSocketPool(
|
| + max_sockets_per_proxy_server(),
|
| + max_sockets_per_group(),
|
| + &transport_for_http_proxy_pool_histograms_,
|
| + host_resolver_,
|
| + socket_factory_,
|
| + net_log_)));
|
| + DCHECK(tcp_http_ret.second);
|
| +
|
| + std::pair<TransportSocketPoolMap::iterator, bool> tcp_https_ret =
|
| + transport_socket_pools_for_https_proxies_.insert(
|
| + std::make_pair(
|
| + http_proxy,
|
| + new TransportClientSocketPool(
|
| + max_sockets_per_proxy_server(),
|
| + max_sockets_per_group(),
|
| + &transport_for_https_proxy_pool_histograms_,
|
| + host_resolver_,
|
| + socket_factory_,
|
| + net_log_)));
|
| + DCHECK(tcp_https_ret.second);
|
| +
|
| + std::pair<SSLSocketPoolMap::iterator, bool> ssl_https_ret =
|
| + ssl_socket_pools_for_https_proxies_.insert(
|
| + std::make_pair(
|
| + http_proxy,
|
| + new SSLClientSocketPool(
|
| + max_sockets_per_proxy_server(),
|
| + max_sockets_per_group(),
|
| + &ssl_for_https_proxy_pool_histograms_,
|
| + host_resolver_,
|
| + cert_verifier_,
|
| + origin_bound_cert_service_,
|
| + dnsrr_resolver_,
|
| + dns_cert_checker_,
|
| + ssl_host_info_factory_,
|
| + socket_factory_,
|
| + tcp_https_ret.first->second /* https proxy */,
|
| + NULL /* no socks proxy */,
|
| + NULL /* no http proxy */,
|
| + ssl_config_service_, net_log_)));
|
| + DCHECK(tcp_https_ret.second);
|
| +
|
| + std::pair<HTTPProxySocketPoolMap::iterator, bool> ret =
|
| + http_proxy_socket_pools_.insert(
|
| + std::make_pair(
|
| + http_proxy,
|
| + new HttpProxyClientSocketPool(
|
| + max_sockets_per_proxy_server(),
|
| + max_sockets_per_group(),
|
| + &http_proxy_pool_histograms_,
|
| + host_resolver_,
|
| + tcp_http_ret.first->second,
|
| + ssl_https_ret.first->second,
|
| + net_log_)));
|
| +
|
| + return ret.first->second;
|
| +}
|
| +
|
| +SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSSLWithProxy(
|
| + const HostPortPair& proxy_server) {
|
| + SSLSocketPoolMap::const_iterator it =
|
| + ssl_socket_pools_for_proxies_.find(proxy_server);
|
| + if (it != ssl_socket_pools_for_proxies_.end())
|
| + return it->second;
|
| +
|
| + SSLClientSocketPool* new_pool = new SSLClientSocketPool(
|
| + max_sockets_per_proxy_server(), max_sockets_per_group(),
|
| + &ssl_pool_histograms_,
|
| + host_resolver_,
|
| + cert_verifier_,
|
| + origin_bound_cert_service_,
|
| + dnsrr_resolver_,
|
| + dns_cert_checker_,
|
| + ssl_host_info_factory_,
|
| + socket_factory_,
|
| + NULL, /* no tcp pool, we always go through a proxy */
|
| + GetSocketPoolForSOCKSProxy(proxy_server),
|
| + GetSocketPoolForHTTPProxy(proxy_server),
|
| + ssl_config_service_,
|
| + net_log_);
|
| +
|
| + std::pair<SSLSocketPoolMap::iterator, bool> ret =
|
| + ssl_socket_pools_for_proxies_.insert(std::make_pair(proxy_server,
|
| + new_pool));
|
| +
|
| + return ret.first->second;
|
| +}
|
| +
|
| +Value* ClientSocketPoolManagerImpl::SocketPoolInfoToValue() const {
|
| + ListValue* list = new ListValue();
|
| + list->Append(transport_socket_pool_->GetInfoAsValue("transport_socket_pool",
|
| + "transport_socket_pool",
|
| + false));
|
| + // Third parameter is false because |ssl_socket_pool_| uses
|
| + // |transport_socket_pool_| internally, and do not want to add it a second
|
| + // time.
|
| + list->Append(ssl_socket_pool_->GetInfoAsValue("ssl_socket_pool",
|
| + "ssl_socket_pool",
|
| + false));
|
| + AddSocketPoolsToList(list,
|
| + http_proxy_socket_pools_,
|
| + "http_proxy_socket_pool",
|
| + true);
|
| + AddSocketPoolsToList(list,
|
| + socks_socket_pools_,
|
| + "socks_socket_pool",
|
| + true);
|
| +
|
| + // Third parameter is false because |ssl_socket_pools_for_proxies_| use
|
| + // socket pools in |http_proxy_socket_pools_| and |socks_socket_pools_|.
|
| + AddSocketPoolsToList(list,
|
| + ssl_socket_pools_for_proxies_,
|
| + "ssl_socket_pool_for_proxies",
|
| + false);
|
| + return list;
|
| +}
|
| +
|
| +void ClientSocketPoolManagerImpl::OnUserCertAdded(const X509Certificate* cert) {
|
| + FlushSocketPools();
|
| +}
|
| +
|
| +void ClientSocketPoolManagerImpl::OnCertTrustChanged(
|
| + const X509Certificate* cert) {
|
| + // We should flush the socket pools if we removed trust from a
|
| + // cert, because a previously trusted server may have become
|
| + // untrusted.
|
| + //
|
| + // We should not flush the socket pools if we added trust to a
|
| + // cert.
|
| + //
|
| + // Since the OnCertTrustChanged method doesn't tell us what
|
| + // kind of trust change it is, we have to flush the socket
|
| + // pools to be safe.
|
| + FlushSocketPools();
|
| +}
|
| +
|
| +} // namespace net
|
|
|