Home | History | Annotate | Download | only in socket
      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.
      4 
      5 #include "net/socket/client_socket_pool_manager_impl.h"
      6 
      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/ssl/ssl_config_service.h"
     15 
     16 namespace net {
     17 
     18 namespace {
     19 
     20 // Appends information about all |socket_pools| to the end of |list|.
     21 template <class MapType>
     22 void AddSocketPoolsToList(base::ListValue* list,
     23                           const MapType& socket_pools,
     24                           const std::string& type,
     25                           bool include_nested_pools) {
     26   for (typename MapType::const_iterator it = socket_pools.begin();
     27        it != socket_pools.end(); it++) {
     28     list->Append(it->second->GetInfoAsValue(it->first.ToString(),
     29                                             type,
     30                                             include_nested_pools));
     31   }
     32 }
     33 
     34 }  // namespace
     35 
     36 ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
     37     NetLog* net_log,
     38     ClientSocketFactory* socket_factory,
     39     HostResolver* host_resolver,
     40     CertVerifier* cert_verifier,
     41     ServerBoundCertService* server_bound_cert_service,
     42     TransportSecurityState* transport_security_state,
     43     CTVerifier* cert_transparency_verifier,
     44     const std::string& ssl_session_cache_shard,
     45     ProxyService* proxy_service,
     46     SSLConfigService* ssl_config_service,
     47     HttpNetworkSession::SocketPoolType pool_type)
     48     : net_log_(net_log),
     49       socket_factory_(socket_factory),
     50       host_resolver_(host_resolver),
     51       cert_verifier_(cert_verifier),
     52       server_bound_cert_service_(server_bound_cert_service),
     53       transport_security_state_(transport_security_state),
     54       cert_transparency_verifier_(cert_transparency_verifier),
     55       ssl_session_cache_shard_(ssl_session_cache_shard),
     56       proxy_service_(proxy_service),
     57       ssl_config_service_(ssl_config_service),
     58       pool_type_(pool_type),
     59       transport_pool_histograms_("TCP"),
     60       transport_socket_pool_(new TransportClientSocketPool(
     61           max_sockets_per_pool(pool_type), max_sockets_per_group(pool_type),
     62           &transport_pool_histograms_,
     63           host_resolver,
     64           socket_factory_,
     65           net_log)),
     66       ssl_pool_histograms_("SSL2"),
     67       ssl_socket_pool_(new SSLClientSocketPool(
     68           max_sockets_per_pool(pool_type), max_sockets_per_group(pool_type),
     69           &ssl_pool_histograms_,
     70           host_resolver,
     71           cert_verifier,
     72           server_bound_cert_service,
     73           transport_security_state,
     74           cert_transparency_verifier,
     75           ssl_session_cache_shard,
     76           socket_factory,
     77           transport_socket_pool_.get(),
     78           NULL /* no socks proxy */,
     79           NULL /* no http proxy */,
     80           ssl_config_service,
     81           net_log)),
     82       transport_for_socks_pool_histograms_("TCPforSOCKS"),
     83       socks_pool_histograms_("SOCK"),
     84       transport_for_http_proxy_pool_histograms_("TCPforHTTPProxy"),
     85       transport_for_https_proxy_pool_histograms_("TCPforHTTPSProxy"),
     86       ssl_for_https_proxy_pool_histograms_("SSLforHTTPSProxy"),
     87       http_proxy_pool_histograms_("HTTPProxy"),
     88       ssl_socket_pool_for_proxies_histograms_("SSLForProxies") {
     89   CertDatabase::GetInstance()->AddObserver(this);
     90 }
     91 
     92 ClientSocketPoolManagerImpl::~ClientSocketPoolManagerImpl() {
     93   CertDatabase::GetInstance()->RemoveObserver(this);
     94 }
     95 
     96 void ClientSocketPoolManagerImpl::FlushSocketPoolsWithError(int error) {
     97   // 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)
    104     it->second->FlushWithError(error);
    105 
    106   for (HTTPProxySocketPoolMap::const_iterator it =
    107        http_proxy_socket_pools_.begin();
    108        it != http_proxy_socket_pools_.end();
    109        ++it)
    110     it->second->FlushWithError(error);
    111 
    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)
    116     it->second->FlushWithError(error);
    117 
    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)
    122     it->second->FlushWithError(error);
    123 
    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)
    128     it->second->FlushWithError(error);
    129 
    130   for (SOCKSSocketPoolMap::const_iterator it =
    131        socks_socket_pools_.begin();
    132        it != socks_socket_pools_.end();
    133        ++it)
    134     it->second->FlushWithError(error);
    135 
    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)
    140     it->second->FlushWithError(error);
    141 
    142   ssl_socket_pool_->FlushWithError(error);
    143   transport_socket_pool_->FlushWithError(error);
    144 }
    145 
    146 void 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 
    195 TransportClientSocketPool*
    196 ClientSocketPoolManagerImpl::GetTransportSocketPool() {
    197   return transport_socket_pool_.get();
    198 }
    199 
    200 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSSLSocketPool() {
    201   return ssl_socket_pool_.get();
    202 }
    203 
    204 SOCKSClientSocketPool* 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));
    213 
    214   std::pair<TransportSocketPoolMap::iterator, bool> tcp_ret =
    215       transport_socket_pools_for_socks_proxies_.insert(
    216           std::make_pair(
    217               socks_proxy,
    218               new TransportClientSocketPool(
    219                   max_sockets_per_proxy_server(pool_type_),
    220                   max_sockets_per_group(pool_type_),
    221                   &transport_for_socks_pool_histograms_,
    222                   host_resolver_,
    223                   socket_factory_,
    224                   net_log_)));
    225   DCHECK(tcp_ret.second);
    226 
    227   std::pair<SOCKSSocketPoolMap::iterator, bool> ret =
    228       socks_socket_pools_.insert(
    229           std::make_pair(socks_proxy, new SOCKSClientSocketPool(
    230               max_sockets_per_proxy_server(pool_type_),
    231               max_sockets_per_group(pool_type_),
    232               &socks_pool_histograms_,
    233               host_resolver_,
    234               tcp_ret.first->second,
    235               net_log_)));
    236 
    237   return ret.first->second;
    238 }
    239 
    240 HttpProxyClientSocketPool*
    241 ClientSocketPoolManagerImpl::GetSocketPoolForHTTPProxy(
    242     const HostPortPair& http_proxy) {
    243   HTTPProxySocketPoolMap::const_iterator it =
    244       http_proxy_socket_pools_.find(http_proxy);
    245   if (it != http_proxy_socket_pools_.end()) {
    246     DCHECK(ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
    247     DCHECK(ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
    248     DCHECK(ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
    249     return it->second;
    250   }
    251 
    252   DCHECK(!ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
    253   DCHECK(!ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
    254   DCHECK(!ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
    255 
    256   std::pair<TransportSocketPoolMap::iterator, bool> tcp_http_ret =
    257       transport_socket_pools_for_http_proxies_.insert(
    258           std::make_pair(
    259               http_proxy,
    260               new TransportClientSocketPool(
    261                   max_sockets_per_proxy_server(pool_type_),
    262                   max_sockets_per_group(pool_type_),
    263                   &transport_for_http_proxy_pool_histograms_,
    264                   host_resolver_,
    265                   socket_factory_,
    266                   net_log_)));
    267   DCHECK(tcp_http_ret.second);
    268 
    269   std::pair<TransportSocketPoolMap::iterator, bool> tcp_https_ret =
    270       transport_socket_pools_for_https_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_https_proxy_pool_histograms_,
    277                   host_resolver_,
    278                   socket_factory_,
    279                   net_log_)));
    280   DCHECK(tcp_https_ret.second);
    281 
    282   std::pair<SSLSocketPoolMap::iterator, bool> ssl_https_ret =
    283       ssl_socket_pools_for_https_proxies_.insert(std::make_pair(
    284           http_proxy,
    285           new SSLClientSocketPool(max_sockets_per_proxy_server(pool_type_),
    286                                   max_sockets_per_group(pool_type_),
    287                                   &ssl_for_https_proxy_pool_histograms_,
    288                                   host_resolver_,
    289                                   cert_verifier_,
    290                                   server_bound_cert_service_,
    291                                   transport_security_state_,
    292                                   cert_transparency_verifier_,
    293                                   ssl_session_cache_shard_,
    294                                   socket_factory_,
    295                                   tcp_https_ret.first->second /* https proxy */,
    296                                   NULL /* no socks proxy */,
    297                                   NULL /* no http proxy */,
    298                                   ssl_config_service_.get(),
    299                                   net_log_)));
    300   DCHECK(tcp_https_ret.second);
    301 
    302   std::pair<HTTPProxySocketPoolMap::iterator, bool> ret =
    303       http_proxy_socket_pools_.insert(
    304           std::make_pair(
    305               http_proxy,
    306               new HttpProxyClientSocketPool(
    307                   max_sockets_per_proxy_server(pool_type_),
    308                   max_sockets_per_group(pool_type_),
    309                   &http_proxy_pool_histograms_,
    310                   host_resolver_,
    311                   tcp_http_ret.first->second,
    312                   ssl_https_ret.first->second,
    313                   net_log_)));
    314 
    315   return ret.first->second;
    316 }
    317 
    318 SSLClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPoolForSSLWithProxy(
    319     const HostPortPair& proxy_server) {
    320   SSLSocketPoolMap::const_iterator it =
    321       ssl_socket_pools_for_proxies_.find(proxy_server);
    322   if (it != ssl_socket_pools_for_proxies_.end())
    323     return it->second;
    324 
    325   SSLClientSocketPool* new_pool = new SSLClientSocketPool(
    326       max_sockets_per_proxy_server(pool_type_),
    327       max_sockets_per_group(pool_type_),
    328       &ssl_pool_histograms_,
    329       host_resolver_,
    330       cert_verifier_,
    331       server_bound_cert_service_,
    332       transport_security_state_,
    333       cert_transparency_verifier_,
    334       ssl_session_cache_shard_,
    335       socket_factory_,
    336       NULL, /* no tcp pool, we always go through a proxy */
    337       GetSocketPoolForSOCKSProxy(proxy_server),
    338       GetSocketPoolForHTTPProxy(proxy_server),
    339       ssl_config_service_.get(),
    340       net_log_);
    341 
    342   std::pair<SSLSocketPoolMap::iterator, bool> ret =
    343       ssl_socket_pools_for_proxies_.insert(std::make_pair(proxy_server,
    344                                                           new_pool));
    345 
    346   return ret.first->second;
    347 }
    348 
    349 base::Value* ClientSocketPoolManagerImpl::SocketPoolInfoToValue() const {
    350   base::ListValue* list = new base::ListValue();
    351   list->Append(transport_socket_pool_->GetInfoAsValue("transport_socket_pool",
    352                                                 "transport_socket_pool",
    353                                                 false));
    354   // Third parameter is false because |ssl_socket_pool_| uses
    355   // |transport_socket_pool_| internally, and do not want to add it a second
    356   // time.
    357   list->Append(ssl_socket_pool_->GetInfoAsValue("ssl_socket_pool",
    358                                                 "ssl_socket_pool",
    359                                                 false));
    360   AddSocketPoolsToList(list,
    361                        http_proxy_socket_pools_,
    362                        "http_proxy_socket_pool",
    363                        true);
    364   AddSocketPoolsToList(list,
    365                        socks_socket_pools_,
    366                        "socks_socket_pool",
    367                        true);
    368 
    369   // Third parameter is false because |ssl_socket_pools_for_proxies_| use
    370   // socket pools in |http_proxy_socket_pools_| and |socks_socket_pools_|.
    371   AddSocketPoolsToList(list,
    372                        ssl_socket_pools_for_proxies_,
    373                        "ssl_socket_pool_for_proxies",
    374                        false);
    375   return list;
    376 }
    377 
    378 void ClientSocketPoolManagerImpl::OnCertAdded(const X509Certificate* cert) {
    379   FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
    380 }
    381 
    382 void ClientSocketPoolManagerImpl::OnCACertChanged(
    383     const X509Certificate* cert) {
    384   // We should flush the socket pools if we removed trust from a
    385   // cert, because a previously trusted server may have become
    386   // untrusted.
    387   //
    388   // We should not flush the socket pools if we added trust to a
    389   // cert.
    390   //
    391   // Since the OnCACertChanged method doesn't tell us what
    392   // kind of change it is, we have to flush the socket
    393   // pools to be safe.
    394   FlushSocketPoolsWithError(ERR_NETWORK_CHANGED);
    395 }
    396 
    397 }  // namespace net
    398