Home | History | Annotate | Download | only in socket
      1 // Copyright (c) 2011 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/ssl_client_socket_pool.h"
      6 
      7 #include "base/metrics/field_trial.h"
      8 #include "base/metrics/histogram.h"
      9 #include "base/values.h"
     10 #include "net/base/net_errors.h"
     11 #include "net/base/host_port_pair.h"
     12 #include "net/base/ssl_cert_request_info.h"
     13 #include "net/http/http_proxy_client_socket.h"
     14 #include "net/http/http_proxy_client_socket_pool.h"
     15 #include "net/socket/client_socket_factory.h"
     16 #include "net/socket/client_socket_handle.h"
     17 #include "net/socket/socks_client_socket_pool.h"
     18 #include "net/socket/ssl_client_socket.h"
     19 #include "net/socket/ssl_host_info.h"
     20 #include "net/socket/transport_client_socket_pool.h"
     21 
     22 namespace net {
     23 
     24 SSLSocketParams::SSLSocketParams(
     25     const scoped_refptr<TransportSocketParams>& transport_params,
     26     const scoped_refptr<SOCKSSocketParams>& socks_params,
     27     const scoped_refptr<HttpProxySocketParams>& http_proxy_params,
     28     ProxyServer::Scheme proxy,
     29     const HostPortPair& host_and_port,
     30     const SSLConfig& ssl_config,
     31     int load_flags,
     32     bool force_spdy_over_ssl,
     33     bool want_spdy_over_npn)
     34     : transport_params_(transport_params),
     35       http_proxy_params_(http_proxy_params),
     36       socks_params_(socks_params),
     37       proxy_(proxy),
     38       host_and_port_(host_and_port),
     39       ssl_config_(ssl_config),
     40       load_flags_(load_flags),
     41       force_spdy_over_ssl_(force_spdy_over_ssl),
     42       want_spdy_over_npn_(want_spdy_over_npn) {
     43   switch (proxy_) {
     44     case ProxyServer::SCHEME_DIRECT:
     45       DCHECK(transport_params_.get() != NULL);
     46       DCHECK(http_proxy_params_.get() == NULL);
     47       DCHECK(socks_params_.get() == NULL);
     48       ignore_limits_ = transport_params_->ignore_limits();
     49       break;
     50     case ProxyServer::SCHEME_HTTP:
     51     case ProxyServer::SCHEME_HTTPS:
     52       DCHECK(transport_params_.get() == NULL);
     53       DCHECK(http_proxy_params_.get() != NULL);
     54       DCHECK(socks_params_.get() == NULL);
     55       ignore_limits_ = http_proxy_params_->ignore_limits();
     56       break;
     57     case ProxyServer::SCHEME_SOCKS4:
     58     case ProxyServer::SCHEME_SOCKS5:
     59       DCHECK(transport_params_.get() == NULL);
     60       DCHECK(http_proxy_params_.get() == NULL);
     61       DCHECK(socks_params_.get() != NULL);
     62       ignore_limits_ = socks_params_->ignore_limits();
     63       break;
     64     default:
     65       LOG(DFATAL) << "unknown proxy type";
     66       break;
     67   }
     68 }
     69 
     70 SSLSocketParams::~SSLSocketParams() {}
     71 
     72 #ifdef ANDROID
     73 bool SSLSocketParams::getUID(uid_t *uid) const {
     74   bool answer = false;
     75   switch (proxy_) {
     76     case ProxyServer::SCHEME_DIRECT:
     77       DCHECK(transport_params_.get() != NULL);
     78       DCHECK(http_proxy_params_.get() == NULL);
     79       DCHECK(socks_params_.get() == NULL);
     80       answer = transport_params_->getUID(uid);
     81       break;
     82     case ProxyServer::SCHEME_HTTP:
     83     case ProxyServer::SCHEME_HTTPS:
     84       DCHECK(transport_params_.get() == NULL);
     85       DCHECK(http_proxy_params_.get() != NULL);
     86       DCHECK(socks_params_.get() == NULL);
     87       answer = http_proxy_params_->getUID(uid);
     88       break;
     89     case ProxyServer::SCHEME_SOCKS4:
     90     case ProxyServer::SCHEME_SOCKS5:
     91       DCHECK(transport_params_.get() == NULL);
     92       DCHECK(http_proxy_params_.get() == NULL);
     93       DCHECK(socks_params_.get() != NULL);
     94       answer = socks_params_->getUID(uid);
     95       break;
     96     default:
     97       break;
     98   }
     99   return answer;
    100 }
    101 
    102 void SSLSocketParams::setUID(uid_t uid) {
    103   switch (proxy_) {
    104     case ProxyServer::SCHEME_DIRECT:
    105       break;
    106     case ProxyServer::SCHEME_HTTP:
    107     case ProxyServer::SCHEME_HTTPS:
    108       http_proxy_params_->setUID(uid);
    109       break;
    110     case ProxyServer::SCHEME_SOCKS4:
    111     case ProxyServer::SCHEME_SOCKS5:
    112       socks_params_->setUID(uid);
    113       break;
    114     default:
    115       break;
    116   }
    117 }
    118 #endif
    119 
    120 // Timeout for the SSL handshake portion of the connect.
    121 static const int kSSLHandshakeTimeoutInSeconds = 30;
    122 
    123 SSLConnectJob::SSLConnectJob(
    124     const std::string& group_name,
    125     const scoped_refptr<SSLSocketParams>& params,
    126     const base::TimeDelta& timeout_duration,
    127     TransportClientSocketPool* transport_pool,
    128     SOCKSClientSocketPool* socks_pool,
    129     HttpProxyClientSocketPool* http_proxy_pool,
    130     ClientSocketFactory* client_socket_factory,
    131     HostResolver* host_resolver,
    132     CertVerifier* cert_verifier,
    133     DnsRRResolver* dnsrr_resolver,
    134     DnsCertProvenanceChecker* dns_cert_checker,
    135     SSLHostInfoFactory* ssl_host_info_factory,
    136     Delegate* delegate,
    137     NetLog* net_log)
    138     : ConnectJob(group_name, timeout_duration, delegate,
    139                  BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
    140       params_(params),
    141       transport_pool_(transport_pool),
    142       socks_pool_(socks_pool),
    143       http_proxy_pool_(http_proxy_pool),
    144       client_socket_factory_(client_socket_factory),
    145       host_resolver_(host_resolver),
    146       cert_verifier_(cert_verifier),
    147       dnsrr_resolver_(dnsrr_resolver),
    148       dns_cert_checker_(dns_cert_checker),
    149       ssl_host_info_factory_(ssl_host_info_factory),
    150       ALLOW_THIS_IN_INITIALIZER_LIST(
    151           callback_(this, &SSLConnectJob::OnIOComplete)) {}
    152 
    153 SSLConnectJob::~SSLConnectJob() {}
    154 
    155 LoadState SSLConnectJob::GetLoadState() const {
    156   switch (next_state_) {
    157     case STATE_TUNNEL_CONNECT_COMPLETE:
    158       if (transport_socket_handle_->socket())
    159         return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL;
    160       // else, fall through.
    161     case STATE_TRANSPORT_CONNECT:
    162     case STATE_TRANSPORT_CONNECT_COMPLETE:
    163     case STATE_SOCKS_CONNECT:
    164     case STATE_SOCKS_CONNECT_COMPLETE:
    165     case STATE_TUNNEL_CONNECT:
    166       return transport_socket_handle_->GetLoadState();
    167     case STATE_SSL_CONNECT:
    168     case STATE_SSL_CONNECT_COMPLETE:
    169       return LOAD_STATE_SSL_HANDSHAKE;
    170     default:
    171       NOTREACHED();
    172       return LOAD_STATE_IDLE;
    173   }
    174 }
    175 
    176 void SSLConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) {
    177   // Headers in |error_response_info_| indicate a proxy tunnel setup
    178   // problem. See DoTunnelConnectComplete.
    179   if (error_response_info_.headers) {
    180     handle->set_pending_http_proxy_connection(
    181         transport_socket_handle_.release());
    182   }
    183   handle->set_ssl_error_response_info(error_response_info_);
    184   if (!ssl_connect_start_time_.is_null())
    185     handle->set_is_ssl_error(true);
    186 }
    187 
    188 void SSLConnectJob::OnIOComplete(int result) {
    189   int rv = DoLoop(result);
    190   if (rv != ERR_IO_PENDING)
    191     NotifyDelegateOfCompletion(rv);  // Deletes |this|.
    192 }
    193 
    194 int SSLConnectJob::DoLoop(int result) {
    195   DCHECK_NE(next_state_, STATE_NONE);
    196 
    197   int rv = result;
    198   do {
    199     State state = next_state_;
    200     next_state_ = STATE_NONE;
    201     switch (state) {
    202       case STATE_TRANSPORT_CONNECT:
    203         DCHECK_EQ(OK, rv);
    204         rv = DoTransportConnect();
    205         break;
    206       case STATE_TRANSPORT_CONNECT_COMPLETE:
    207         rv = DoTransportConnectComplete(rv);
    208         break;
    209       case STATE_SOCKS_CONNECT:
    210         DCHECK_EQ(OK, rv);
    211         rv = DoSOCKSConnect();
    212         break;
    213       case STATE_SOCKS_CONNECT_COMPLETE:
    214         rv = DoSOCKSConnectComplete(rv);
    215         break;
    216       case STATE_TUNNEL_CONNECT:
    217         DCHECK_EQ(OK, rv);
    218         rv = DoTunnelConnect();
    219         break;
    220       case STATE_TUNNEL_CONNECT_COMPLETE:
    221         rv = DoTunnelConnectComplete(rv);
    222         break;
    223       case STATE_SSL_CONNECT:
    224         DCHECK_EQ(OK, rv);
    225         rv = DoSSLConnect();
    226         break;
    227       case STATE_SSL_CONNECT_COMPLETE:
    228         rv = DoSSLConnectComplete(rv);
    229         break;
    230       default:
    231         NOTREACHED() << "bad state";
    232         rv = ERR_FAILED;
    233         break;
    234     }
    235   } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
    236 
    237   return rv;
    238 }
    239 
    240 int SSLConnectJob::DoTransportConnect() {
    241   DCHECK(transport_pool_);
    242 
    243   if (ssl_host_info_factory_) {
    244       ssl_host_info_.reset(
    245           ssl_host_info_factory_->GetForHost(params_->host_and_port().host(),
    246                                              params_->ssl_config()));
    247   }
    248 
    249   if (ssl_host_info_.get()) {
    250     if (dnsrr_resolver_)
    251       ssl_host_info_->StartDnsLookup(dnsrr_resolver_);
    252 
    253     // This starts fetching the SSL host info from the disk cache for Snap
    254     // Start.
    255     ssl_host_info_->Start();
    256   }
    257 
    258   next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE;
    259   transport_socket_handle_.reset(new ClientSocketHandle());
    260   scoped_refptr<TransportSocketParams> transport_params =
    261       params_->transport_params();
    262   return transport_socket_handle_->Init(
    263       group_name(),
    264       transport_params,
    265       transport_params->destination().priority(),
    266       &callback_, transport_pool_, net_log());
    267 }
    268 
    269 int SSLConnectJob::DoTransportConnectComplete(int result) {
    270   if (result == OK)
    271     next_state_ = STATE_SSL_CONNECT;
    272 
    273   return result;
    274 }
    275 
    276 int SSLConnectJob::DoSOCKSConnect() {
    277   DCHECK(socks_pool_);
    278   next_state_ = STATE_SOCKS_CONNECT_COMPLETE;
    279   transport_socket_handle_.reset(new ClientSocketHandle());
    280   scoped_refptr<SOCKSSocketParams> socks_params = params_->socks_params();
    281   return transport_socket_handle_->Init(group_name(), socks_params,
    282                                         socks_params->destination().priority(),
    283                                         &callback_, socks_pool_, net_log());
    284 }
    285 
    286 int SSLConnectJob::DoSOCKSConnectComplete(int result) {
    287   if (result == OK)
    288     next_state_ = STATE_SSL_CONNECT;
    289 
    290   return result;
    291 }
    292 
    293 int SSLConnectJob::DoTunnelConnect() {
    294   DCHECK(http_proxy_pool_);
    295   next_state_ = STATE_TUNNEL_CONNECT_COMPLETE;
    296 
    297   transport_socket_handle_.reset(new ClientSocketHandle());
    298   scoped_refptr<HttpProxySocketParams> http_proxy_params =
    299       params_->http_proxy_params();
    300   return transport_socket_handle_->Init(
    301       group_name(), http_proxy_params,
    302       http_proxy_params->destination().priority(), &callback_,
    303       http_proxy_pool_, net_log());
    304 }
    305 
    306 int SSLConnectJob::DoTunnelConnectComplete(int result) {
    307   // Extract the information needed to prompt for appropriate proxy
    308   // authentication so that when ClientSocketPoolBaseHelper calls
    309   // |GetAdditionalErrorState|, we can easily set the state.
    310   if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
    311     error_response_info_ = transport_socket_handle_->ssl_error_response_info();
    312   } else if (result == ERR_PROXY_AUTH_REQUESTED ||
    313              result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) {
    314     ClientSocket* socket = transport_socket_handle_->socket();
    315     HttpProxyClientSocket* tunnel_socket =
    316         static_cast<HttpProxyClientSocket*>(socket);
    317     error_response_info_ = *tunnel_socket->GetConnectResponseInfo();
    318   }
    319   if (result < 0)
    320     return result;
    321 
    322   next_state_ = STATE_SSL_CONNECT;
    323   return result;
    324 }
    325 
    326 int SSLConnectJob::DoSSLConnect() {
    327   next_state_ = STATE_SSL_CONNECT_COMPLETE;
    328   // Reset the timeout to just the time allowed for the SSL handshake.
    329   ResetTimer(base::TimeDelta::FromSeconds(kSSLHandshakeTimeoutInSeconds));
    330   ssl_connect_start_time_ = base::TimeTicks::Now();
    331 
    332   ssl_socket_.reset(client_socket_factory_->CreateSSLClientSocket(
    333       transport_socket_handle_.release(), params_->host_and_port(),
    334       params_->ssl_config(), ssl_host_info_.release(), cert_verifier_,
    335       dns_cert_checker_));
    336 
    337 #ifdef ANDROID
    338   uid_t calling_uid = 0;
    339   bool valid_uid = params_->getUID(&calling_uid);
    340 #endif
    341 
    342   return ssl_socket_->Connect(&callback_
    343 #ifdef ANDROID
    344                               , params_->ignore_limits()
    345                               , valid_uid
    346                               , calling_uid
    347 #endif
    348                              );
    349 }
    350 
    351 int SSLConnectJob::DoSSLConnectComplete(int result) {
    352   SSLClientSocket::NextProtoStatus status =
    353       SSLClientSocket::kNextProtoUnsupported;
    354   std::string proto;
    355   // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket
    356   // that hasn't had SSL_ImportFD called on it. If we get a certificate error
    357   // here, then we know that we called SSL_ImportFD.
    358   if (result == OK || IsCertificateError(result))
    359     status = ssl_socket_->GetNextProto(&proto);
    360 
    361   // If we want spdy over npn, make sure it succeeded.
    362   if (status == SSLClientSocket::kNextProtoNegotiated) {
    363     ssl_socket_->set_was_npn_negotiated(true);
    364     SSLClientSocket::NextProto next_protocol =
    365         SSLClientSocket::NextProtoFromString(proto);
    366     // If we negotiated either version of SPDY, we must have
    367     // advertised it, so allow it.
    368     // TODO(mbelshe): verify it was a protocol we advertised?
    369     if (next_protocol == SSLClientSocket::kProtoSPDY1 ||
    370         next_protocol == SSLClientSocket::kProtoSPDY2) {
    371       ssl_socket_->set_was_spdy_negotiated(true);
    372     }
    373   }
    374   if (params_->want_spdy_over_npn() && !ssl_socket_->was_spdy_negotiated())
    375     return ERR_NPN_NEGOTIATION_FAILED;
    376 
    377   // Spdy might be turned on by default, or it might be over npn.
    378   bool using_spdy = params_->force_spdy_over_ssl() ||
    379       params_->want_spdy_over_npn();
    380 
    381   if (result == OK ||
    382       ssl_socket_->IgnoreCertError(result, params_->load_flags())) {
    383     DCHECK(ssl_connect_start_time_ != base::TimeTicks());
    384     base::TimeDelta connect_duration =
    385         base::TimeTicks::Now() - ssl_connect_start_time_;
    386     if (using_spdy) {
    387       UMA_HISTOGRAM_CUSTOM_TIMES("Net.SpdyConnectionLatency",
    388                                  connect_duration,
    389                                  base::TimeDelta::FromMilliseconds(1),
    390                                  base::TimeDelta::FromMinutes(10),
    391                                  100);
    392     } else {
    393       UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency",
    394                                  connect_duration,
    395                                  base::TimeDelta::FromMilliseconds(1),
    396                                  base::TimeDelta::FromMinutes(10),
    397                                  100);
    398 
    399       const std::string& host = params_->host_and_port().host();
    400       bool is_google = host == "google.com" ||
    401                        host.rfind(".google.com") == host.size() - 11;
    402       if (is_google) {
    403         UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google",
    404                                    connect_duration,
    405                                    base::TimeDelta::FromMilliseconds(1),
    406                                    base::TimeDelta::FromMinutes(10),
    407                                    100);
    408       }
    409 
    410       static bool false_start_trial(
    411           base::FieldTrialList::Find("SSLFalseStart") &&
    412           !base::FieldTrialList::Find("SSLFalseStart")->group_name().empty());
    413       if (false_start_trial) {
    414         UMA_HISTOGRAM_CUSTOM_TIMES(base::FieldTrial::MakeName(
    415                                        "Net.SSL_Connection_Latency",
    416                                        "SSLFalseStart"),
    417                                    connect_duration,
    418                                    base::TimeDelta::FromMilliseconds(1),
    419                                    base::TimeDelta::FromMinutes(10),
    420                                    100);
    421       }
    422     }
    423   }
    424 
    425   if (result == OK || IsCertificateError(result)) {
    426     set_socket(ssl_socket_.release());
    427   } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
    428     error_response_info_.cert_request_info = new SSLCertRequestInfo;
    429     ssl_socket_->GetSSLCertRequestInfo(error_response_info_.cert_request_info);
    430   }
    431 
    432   return result;
    433 }
    434 
    435 int SSLConnectJob::ConnectInternal() {
    436   switch (params_->proxy()) {
    437     case ProxyServer::SCHEME_DIRECT:
    438       next_state_ = STATE_TRANSPORT_CONNECT;
    439       break;
    440     case ProxyServer::SCHEME_HTTP:
    441     case ProxyServer::SCHEME_HTTPS:
    442       next_state_ = STATE_TUNNEL_CONNECT;
    443       break;
    444     case ProxyServer::SCHEME_SOCKS4:
    445     case ProxyServer::SCHEME_SOCKS5:
    446       next_state_ = STATE_SOCKS_CONNECT;
    447       break;
    448     default:
    449       NOTREACHED() << "unknown proxy type";
    450       break;
    451   }
    452   return DoLoop(OK);
    453 }
    454 
    455 SSLClientSocketPool::SSLConnectJobFactory::SSLConnectJobFactory(
    456     TransportClientSocketPool* transport_pool,
    457     SOCKSClientSocketPool* socks_pool,
    458     HttpProxyClientSocketPool* http_proxy_pool,
    459     ClientSocketFactory* client_socket_factory,
    460     HostResolver* host_resolver,
    461     CertVerifier* cert_verifier,
    462     DnsRRResolver* dnsrr_resolver,
    463     DnsCertProvenanceChecker* dns_cert_checker,
    464     SSLHostInfoFactory* ssl_host_info_factory,
    465     NetLog* net_log)
    466     : transport_pool_(transport_pool),
    467       socks_pool_(socks_pool),
    468       http_proxy_pool_(http_proxy_pool),
    469       client_socket_factory_(client_socket_factory),
    470       host_resolver_(host_resolver),
    471       cert_verifier_(cert_verifier),
    472       dnsrr_resolver_(dnsrr_resolver),
    473       dns_cert_checker_(dns_cert_checker),
    474       ssl_host_info_factory_(ssl_host_info_factory),
    475       net_log_(net_log) {
    476   base::TimeDelta max_transport_timeout = base::TimeDelta();
    477   base::TimeDelta pool_timeout;
    478   if (transport_pool_)
    479     max_transport_timeout = transport_pool_->ConnectionTimeout();
    480   if (socks_pool_) {
    481     pool_timeout = socks_pool_->ConnectionTimeout();
    482     if (pool_timeout > max_transport_timeout)
    483       max_transport_timeout = pool_timeout;
    484   }
    485   if (http_proxy_pool_) {
    486     pool_timeout = http_proxy_pool_->ConnectionTimeout();
    487     if (pool_timeout > max_transport_timeout)
    488       max_transport_timeout = pool_timeout;
    489   }
    490   timeout_ = max_transport_timeout +
    491       base::TimeDelta::FromSeconds(kSSLHandshakeTimeoutInSeconds);
    492 }
    493 
    494 SSLClientSocketPool::SSLClientSocketPool(
    495     int max_sockets,
    496     int max_sockets_per_group,
    497     ClientSocketPoolHistograms* histograms,
    498     HostResolver* host_resolver,
    499     CertVerifier* cert_verifier,
    500     DnsRRResolver* dnsrr_resolver,
    501     DnsCertProvenanceChecker* dns_cert_checker,
    502     SSLHostInfoFactory* ssl_host_info_factory,
    503     ClientSocketFactory* client_socket_factory,
    504     TransportClientSocketPool* transport_pool,
    505     SOCKSClientSocketPool* socks_pool,
    506     HttpProxyClientSocketPool* http_proxy_pool,
    507     SSLConfigService* ssl_config_service,
    508     NetLog* net_log)
    509     : transport_pool_(transport_pool),
    510       socks_pool_(socks_pool),
    511       http_proxy_pool_(http_proxy_pool),
    512       base_(max_sockets, max_sockets_per_group, histograms,
    513             base::TimeDelta::FromSeconds(
    514                 ClientSocketPool::unused_idle_socket_timeout()),
    515             base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout),
    516             new SSLConnectJobFactory(transport_pool,
    517                                      socks_pool,
    518                                      http_proxy_pool,
    519                                      client_socket_factory,
    520                                      host_resolver,
    521                                      cert_verifier,
    522                                      dnsrr_resolver,
    523                                      dns_cert_checker,
    524                                      ssl_host_info_factory,
    525                                      net_log)),
    526       ssl_config_service_(ssl_config_service) {
    527   if (ssl_config_service_)
    528     ssl_config_service_->AddObserver(this);
    529 }
    530 
    531 SSLClientSocketPool::~SSLClientSocketPool() {
    532   if (ssl_config_service_)
    533     ssl_config_service_->RemoveObserver(this);
    534 }
    535 
    536 ConnectJob* SSLClientSocketPool::SSLConnectJobFactory::NewConnectJob(
    537     const std::string& group_name,
    538     const PoolBase::Request& request,
    539     ConnectJob::Delegate* delegate) const {
    540   return new SSLConnectJob(group_name, request.params(), ConnectionTimeout(),
    541                            transport_pool_, socks_pool_, http_proxy_pool_,
    542                            client_socket_factory_, host_resolver_,
    543                            cert_verifier_, dnsrr_resolver_, dns_cert_checker_,
    544                            ssl_host_info_factory_, delegate, net_log_);
    545 }
    546 
    547 int SSLClientSocketPool::RequestSocket(const std::string& group_name,
    548                                        const void* socket_params,
    549                                        RequestPriority priority,
    550                                        ClientSocketHandle* handle,
    551                                        CompletionCallback* callback,
    552                                        const BoundNetLog& net_log) {
    553   const scoped_refptr<SSLSocketParams>* casted_socket_params =
    554       static_cast<const scoped_refptr<SSLSocketParams>*>(socket_params);
    555 
    556   return base_.RequestSocket(group_name, *casted_socket_params, priority,
    557                              handle, callback, net_log);
    558 }
    559 
    560 void SSLClientSocketPool::RequestSockets(
    561     const std::string& group_name,
    562     const void* params,
    563     int num_sockets,
    564     const BoundNetLog& net_log) {
    565   const scoped_refptr<SSLSocketParams>* casted_params =
    566       static_cast<const scoped_refptr<SSLSocketParams>*>(params);
    567 
    568   base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
    569 }
    570 
    571 void SSLClientSocketPool::CancelRequest(const std::string& group_name,
    572                                         ClientSocketHandle* handle) {
    573   base_.CancelRequest(group_name, handle);
    574 }
    575 
    576 void SSLClientSocketPool::ReleaseSocket(const std::string& group_name,
    577                                         ClientSocket* socket, int id) {
    578   base_.ReleaseSocket(group_name, socket, id);
    579 }
    580 
    581 void SSLClientSocketPool::Flush() {
    582   base_.Flush();
    583 }
    584 
    585 void SSLClientSocketPool::CloseIdleSockets() {
    586   base_.CloseIdleSockets();
    587 }
    588 
    589 int SSLClientSocketPool::IdleSocketCount() const {
    590   return base_.idle_socket_count();
    591 }
    592 
    593 int SSLClientSocketPool::IdleSocketCountInGroup(
    594     const std::string& group_name) const {
    595   return base_.IdleSocketCountInGroup(group_name);
    596 }
    597 
    598 LoadState SSLClientSocketPool::GetLoadState(
    599     const std::string& group_name, const ClientSocketHandle* handle) const {
    600   return base_.GetLoadState(group_name, handle);
    601 }
    602 
    603 DictionaryValue* SSLClientSocketPool::GetInfoAsValue(
    604     const std::string& name,
    605     const std::string& type,
    606     bool include_nested_pools) const {
    607   DictionaryValue* dict = base_.GetInfoAsValue(name, type);
    608   if (include_nested_pools) {
    609     ListValue* list = new ListValue();
    610     if (transport_pool_) {
    611       list->Append(transport_pool_->GetInfoAsValue("transport_socket_pool",
    612                                                    "transport_socket_pool",
    613                                                    false));
    614     }
    615     if (socks_pool_) {
    616       list->Append(socks_pool_->GetInfoAsValue("socks_pool",
    617                                                "socks_pool",
    618                                                true));
    619     }
    620     if (http_proxy_pool_) {
    621       list->Append(http_proxy_pool_->GetInfoAsValue("http_proxy_pool",
    622                                                     "http_proxy_pool",
    623                                                     true));
    624     }
    625     dict->Set("nested_pools", list);
    626   }
    627   return dict;
    628 }
    629 
    630 base::TimeDelta SSLClientSocketPool::ConnectionTimeout() const {
    631   return base_.ConnectionTimeout();
    632 }
    633 
    634 ClientSocketPoolHistograms* SSLClientSocketPool::histograms() const {
    635   return base_.histograms();
    636 }
    637 
    638 void SSLClientSocketPool::OnSSLConfigChanged() {
    639   Flush();
    640 }
    641 
    642 }  // namespace net
    643