ssl_client_socket_pool.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket_pool.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/field_trial.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/metrics/sparse_histogram.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/host_port_pair.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_proxy_client_socket.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_proxy_client_socket_pool.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_factory.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_handle.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/socks_client_socket_pool.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/transport_client_socket_pool.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_cert_request_info.h"
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/ssl/ssl_connection_status_flags.h"
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/ssl/ssl_info.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLSocketParams::SSLSocketParams(
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<TransportSocketParams>& transport_params,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<SOCKSSocketParams>& socks_params,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<HttpProxySocketParams>& http_proxy_params,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyServer::Scheme proxy,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HostPortPair& host_and_port,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SSLConfig& ssl_config,
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    PrivacyMode privacy_mode,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int load_flags,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool force_spdy_over_ssl,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool want_spdy_over_npn)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : transport_params_(transport_params),
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_proxy_params_(http_proxy_params),
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socks_params_(socks_params),
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_(proxy),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_and_port_(host_and_port),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ssl_config_(ssl_config),
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      privacy_mode_(privacy_mode),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      load_flags_(load_flags),
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      force_spdy_over_ssl_(force_spdy_over_ssl),
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      want_spdy_over_npn_(want_spdy_over_npn),
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ignore_limits_(false) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (proxy_) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ProxyServer::SCHEME_DIRECT:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(transport_params_.get() != NULL);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(http_proxy_params_.get() == NULL);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(socks_params_.get() == NULL);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ignore_limits_ = transport_params_->ignore_limits();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ProxyServer::SCHEME_HTTP:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ProxyServer::SCHEME_HTTPS:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(transport_params_.get() == NULL);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(http_proxy_params_.get() != NULL);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(socks_params_.get() == NULL);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ignore_limits_ = http_proxy_params_->ignore_limits();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ProxyServer::SCHEME_SOCKS4:
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ProxyServer::SCHEME_SOCKS5:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(transport_params_.get() == NULL);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(http_proxy_params_.get() == NULL);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(socks_params_.get() != NULL);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ignore_limits_ = socks_params_->ignore_limits();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(DFATAL) << "unknown proxy type";
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLSocketParams::~SSLSocketParams() {}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Timeout for the SSL handshake portion of the connect.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSSLHandshakeTimeoutInSeconds = 30;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLConnectJob::SSLConnectJob(const std::string& group_name,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const scoped_refptr<SSLSocketParams>& params,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const base::TimeDelta& timeout_duration,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             TransportClientSocketPool* transport_pool,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             SOCKSClientSocketPool* socks_pool,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             HttpProxyClientSocketPool* http_proxy_pool,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ClientSocketFactory* client_socket_factory,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             HostResolver* host_resolver,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const SSLClientSocketContext& context,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             Delegate* delegate,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             NetLog* net_log)
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    : ConnectJob(group_name,
947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 timeout_duration,
957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 delegate,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params_(params),
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transport_pool_(transport_pool),
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socks_pool_(socks_pool),
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_proxy_pool_(http_proxy_pool),
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_socket_factory_(client_socket_factory),
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_resolver_(host_resolver),
1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      context_(context.cert_verifier,
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch               context.server_bound_cert_service,
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch               context.transport_security_state,
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch               (params->privacy_mode() == kPrivacyModeEnabled
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    ? "pm/" + context.ssl_session_cache_shard
1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    : context.ssl_session_cache_shard)),
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      callback_(base::Bind(&SSLConnectJob::OnIOComplete,
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           base::Unretained(this))) {}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLConnectJob::~SSLConnectJob() {}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadState SSLConnectJob::GetLoadState() const {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (next_state_) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_TUNNEL_CONNECT_COMPLETE:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (transport_socket_handle_->socket())
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // else, fall through.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_TRANSPORT_CONNECT:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_TRANSPORT_CONNECT_COMPLETE:
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_SOCKS_CONNECT:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_SOCKS_CONNECT_COMPLETE:
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_TUNNEL_CONNECT:
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return transport_socket_handle_->GetLoadState();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_SSL_CONNECT:
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_SSL_CONNECT_COMPLETE:
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return LOAD_STATE_SSL_HANDSHAKE;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return LOAD_STATE_IDLE;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLConnectJob::GetAdditionalErrorState(ClientSocketHandle* handle) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Headers in |error_response_info_| indicate a proxy tunnel setup
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // problem. See DoTunnelConnectComplete.
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (error_response_info_.headers.get()) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handle->set_pending_http_proxy_connection(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        transport_socket_handle_.release());
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle->set_ssl_error_response_info(error_response_info_);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!connect_timing_.ssl_start.is_null())
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handle->set_is_ssl_error(true);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLConnectJob::OnIOComplete(int result) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = DoLoop(result);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv != ERR_IO_PENDING)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyDelegateOfCompletion(rv);  // Deletes |this|.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoLoop(int result) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(next_state_, STATE_NONE);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = result;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state = next_state_;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    next_state_ = STATE_NONE;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (state) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_TRANSPORT_CONNECT:
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_EQ(OK, rv);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoTransportConnect();
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_TRANSPORT_CONNECT_COMPLETE:
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoTransportConnectComplete(rv);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_SOCKS_CONNECT:
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_EQ(OK, rv);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoSOCKSConnect();
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_SOCKS_CONNECT_COMPLETE:
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoSOCKSConnectComplete(rv);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_TUNNEL_CONNECT:
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_EQ(OK, rv);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoTunnelConnect();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_TUNNEL_CONNECT_COMPLETE:
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoTunnelConnectComplete(rv);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_SSL_CONNECT:
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_EQ(OK, rv);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoSSLConnect();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_SSL_CONNECT_COMPLETE:
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoSSLConnectComplete(rv);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED() << "bad state";
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ERR_FAILED;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rv;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoTransportConnect() {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(transport_pool_);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transport_socket_handle_.reset(new ClientSocketHandle());
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TransportSocketParams> transport_params =
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params_->transport_params();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return transport_socket_handle_->Init(
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      group_name(), transport_params,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transport_params->destination().priority(), callback_, transport_pool_,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net_log());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoTransportConnectComplete(int result) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == OK)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    next_state_ = STATE_SSL_CONNECT;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoSOCKSConnect() {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(socks_pool_);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_SOCKS_CONNECT_COMPLETE;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transport_socket_handle_.reset(new ClientSocketHandle());
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SOCKSSocketParams> socks_params = params_->socks_params();
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return transport_socket_handle_->Init(
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      group_name(), socks_params, socks_params->destination().priority(),
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback_, socks_pool_, net_log());
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoSOCKSConnectComplete(int result) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == OK)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    next_state_ = STATE_SSL_CONNECT;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoTunnelConnect() {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(http_proxy_pool_);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_TUNNEL_CONNECT_COMPLETE;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transport_socket_handle_.reset(new ClientSocketHandle());
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpProxySocketParams> http_proxy_params =
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params_->http_proxy_params();
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return transport_socket_handle_->Init(
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      group_name(), http_proxy_params,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_proxy_params->destination().priority(), callback_, http_proxy_pool_,
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net_log());
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoTunnelConnectComplete(int result) {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Extract the information needed to prompt for appropriate proxy
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // authentication so that when ClientSocketPoolBaseHelper calls
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |GetAdditionalErrorState|, we can easily set the state.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_response_info_ = transport_socket_handle_->ssl_error_response_info();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (result == ERR_PROXY_AUTH_REQUESTED ||
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StreamSocket* socket = transport_socket_handle_->socket();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpProxyClientSocket* tunnel_socket =
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<HttpProxyClientSocket*>(socket);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_response_info_ = *tunnel_socket->GetConnectResponseInfo();
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result < 0)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_SSL_CONNECT;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoSSLConnect() {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_SSL_CONNECT_COMPLETE;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset the timeout to just the time allowed for the SSL handshake.
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResetTimer(base::TimeDelta::FromSeconds(kSSLHandshakeTimeoutInSeconds));
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the handle has a fresh socket, get its connect start and DNS times.
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should always be the case.
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const LoadTimingInfo::ConnectTiming& socket_connect_timing =
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      transport_socket_handle_->connect_timing();
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!transport_socket_handle_->is_reused() &&
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !socket_connect_timing.connect_start.is_null()) {
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Overwriting |connect_start| serves two purposes - it adjusts timing so
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // |connect_start| doesn't include dns times, and it adjusts the time so
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // as not to include time spent waiting for an idle socket.
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    connect_timing_.connect_start = socket_connect_timing.connect_start;
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    connect_timing_.dns_start = socket_connect_timing.dns_start;
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    connect_timing_.dns_end = socket_connect_timing.dns_end;
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  connect_timing_.ssl_start = base::TimeTicks::Now();
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_socket_.reset(client_socket_factory_->CreateSSLClientSocket(
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      transport_socket_handle_.release(),
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      params_->host_and_port(),
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      params_->ssl_config(),
2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      context_));
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ssl_socket_->Connect(callback_);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoSSLConnectComplete(int result) {
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  connect_timing_.ssl_end = base::TimeTicks::Now();
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLClientSocket::NextProtoStatus status =
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SSLClientSocket::kNextProtoUnsupported;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string proto;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string server_protos;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that hasn't had SSL_ImportFD called on it. If we get a certificate error
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // here, then we know that we called SSL_ImportFD.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == OK || IsCertificateError(result))
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status = ssl_socket_->GetNextProto(&proto, &server_protos);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we want spdy over npn, make sure it succeeded.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status == SSLClientSocket::kNextProtoNegotiated) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_socket_->set_was_npn_negotiated(true);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NextProto protocol_negotiated =
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SSLClientSocket::NextProtoFromString(proto);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_socket_->set_protocol_negotiated(protocol_negotiated);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If we negotiated a SPDY version, it must have been present in
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // SSLConfig::next_protos.
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(mbelshe): Verify this.
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (protocol_negotiated >= kProtoSPDYMinimumVersion &&
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        protocol_negotiated <= kProtoSPDYMaximumVersion) {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ssl_socket_->set_was_spdy_negotiated(true);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params_->want_spdy_over_npn() && !ssl_socket_->was_spdy_negotiated())
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_NPN_NEGOTIATION_FAILED;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Spdy might be turned on by default, or it might be over npn.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool using_spdy = params_->force_spdy_over_ssl() ||
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params_->want_spdy_over_npn();
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == OK ||
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ssl_socket_->IgnoreCertError(result, params_->load_flags())) {
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!connect_timing_.ssl_start.is_null());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta connect_duration =
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        connect_timing_.ssl_end - connect_timing_.ssl_start;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (using_spdy) {
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UMA_HISTOGRAM_CUSTOM_TIMES("Net.SpdyConnectionLatency_2",
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 connect_duration,
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::TimeDelta::FromMilliseconds(1),
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 base::TimeDelta::FromMinutes(1),
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 100);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(SPDY_PROXY_AUTH_ORIGIN)
3457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bool using_data_reduction_proxy = params_->host_and_port().Equals(
3467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN)));
3477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (using_data_reduction_proxy) {
3487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      UMA_HISTOGRAM_CUSTOM_TIMES(
3497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          "Net.SSL_Connection_Latency_DataReductionProxy",
3507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          connect_duration,
3517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          base::TimeDelta::FromMilliseconds(1),
3527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          base::TimeDelta::FromMinutes(1),
3537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          100);
3547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
3557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_2",
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               connect_duration,
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(1),
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               base::TimeDelta::FromMinutes(1),
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               100);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSLInfo ssl_info;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_socket_->GetSSLInfo(&ssl_info);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_CipherSuite",
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                SSLConnectionStatusToCipherSuite(
368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                    ssl_info.connection_status));
369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Resume_Handshake",
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 connect_duration,
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::TimeDelta::FromMilliseconds(1),
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::TimeDelta::FromMinutes(1),
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 100);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_FULL) {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Full_Handshake",
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 connect_duration,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::TimeDelta::FromMilliseconds(1),
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::TimeDelta::FromMinutes(1),
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 100);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& host = params_->host_and_port().host();
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_google = host == "google.com" ||
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     (host.size() > 11 &&
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      host.rfind(".google.com") == host.size() - 11);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_google) {
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google2",
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 connect_duration,
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::TimeDelta::FromMilliseconds(1),
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 base::TimeDelta::FromMinutes(1),
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 100);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google_"
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       "Resume_Handshake",
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   connect_duration,
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   base::TimeDelta::FromMilliseconds(1),
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   base::TimeDelta::FromMinutes(1),
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   100);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_FULL) {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google_"
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       "Full_Handshake",
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   connect_duration,
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   base::TimeDelta::FromMilliseconds(1),
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   base::TimeDelta::FromMinutes(1),
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   100);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == OK || IsCertificateError(result)) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_socket(ssl_socket_.release());
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_response_info_.cert_request_info = new SSLCertRequestInfo;
416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ssl_socket_->GetSSLCertRequestInfo(
417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        error_response_info_.cert_request_info.get());
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::ConnectInternal() {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (params_->proxy()) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ProxyServer::SCHEME_DIRECT:
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      next_state_ = STATE_TRANSPORT_CONNECT;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ProxyServer::SCHEME_HTTP:
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ProxyServer::SCHEME_HTTPS:
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      next_state_ = STATE_TUNNEL_CONNECT;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ProxyServer::SCHEME_SOCKS4:
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ProxyServer::SCHEME_SOCKS5:
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      next_state_ = STATE_SOCKS_CONNECT;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "unknown proxy type";
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return DoLoop(OK);
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLClientSocketPool::SSLConnectJobFactory::SSLConnectJobFactory(
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TransportClientSocketPool* transport_pool,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SOCKSClientSocketPool* socks_pool,
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpProxyClientSocketPool* http_proxy_pool,
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClientSocketFactory* client_socket_factory,
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SSLClientSocketContext& context,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetLog* net_log)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : transport_pool_(transport_pool),
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socks_pool_(socks_pool),
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_proxy_pool_(http_proxy_pool),
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_socket_factory_(client_socket_factory),
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_resolver_(host_resolver),
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_(context),
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net_log_(net_log) {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta max_transport_timeout = base::TimeDelta();
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta pool_timeout;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (transport_pool_)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    max_transport_timeout = transport_pool_->ConnectionTimeout();
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (socks_pool_) {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pool_timeout = socks_pool_->ConnectionTimeout();
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pool_timeout > max_transport_timeout)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_transport_timeout = pool_timeout;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (http_proxy_pool_) {
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pool_timeout = http_proxy_pool_->ConnectionTimeout();
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pool_timeout > max_transport_timeout)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_transport_timeout = pool_timeout;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  timeout_ = max_transport_timeout +
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromSeconds(kSSLHandshakeTimeoutInSeconds);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLClientSocketPool::SSLClientSocketPool(
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int max_sockets,
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int max_sockets_per_group,
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClientSocketPoolHistograms* histograms,
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* cert_verifier,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ServerBoundCertService* server_bound_cert_service,
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TransportSecurityState* transport_security_state,
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& ssl_session_cache_shard,
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClientSocketFactory* client_socket_factory,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TransportClientSocketPool* transport_pool,
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SOCKSClientSocketPool* socks_pool,
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpProxyClientSocketPool* http_proxy_pool,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSLConfigService* ssl_config_service,
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetLog* net_log)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : transport_pool_(transport_pool),
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socks_pool_(socks_pool),
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_proxy_pool_(http_proxy_pool),
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base_(max_sockets, max_sockets_per_group, histograms,
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ClientSocketPool::unused_idle_socket_timeout(),
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ClientSocketPool::used_idle_socket_timeout(),
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            new SSLConnectJobFactory(transport_pool,
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     socks_pool,
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     http_proxy_pool,
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     client_socket_factory,
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     host_resolver,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     SSLClientSocketContext(
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         cert_verifier,
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         server_bound_cert_service,
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         transport_security_state,
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         ssl_session_cache_shard),
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     net_log)),
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ssl_config_service_(ssl_config_service) {
509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (ssl_config_service_.get())
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_config_service_->AddObserver(this);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (transport_pool_)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    transport_pool_->AddLayeredPool(this);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (socks_pool_)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socks_pool_->AddLayeredPool(this);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (http_proxy_pool_)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    http_proxy_pool_->AddLayeredPool(this);
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLClientSocketPool::~SSLClientSocketPool() {
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (http_proxy_pool_)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    http_proxy_pool_->RemoveLayeredPool(this);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (socks_pool_)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socks_pool_->RemoveLayeredPool(this);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (transport_pool_)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    transport_pool_->RemoveLayeredPool(this);
526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (ssl_config_service_.get())
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_config_service_->RemoveObserver(this);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ConnectJob* SSLClientSocketPool::SSLConnectJobFactory::NewConnectJob(
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& group_name,
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PoolBase::Request& request,
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConnectJob::Delegate* delegate) const {
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new SSLConnectJob(group_name, request.params(), ConnectionTimeout(),
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           transport_pool_, socks_pool_, http_proxy_pool_,
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           client_socket_factory_, host_resolver_,
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           context_, delegate, net_log_);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLClientSocketPool::SSLConnectJobFactory::ConnectionTimeout() const {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return timeout_;
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLClientSocketPool::RequestSocket(const std::string& group_name,
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const void* socket_params,
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       RequestPriority priority,
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       ClientSocketHandle* handle,
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const CompletionCallback& callback,
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const BoundNetLog& net_log) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_refptr<SSLSocketParams>* casted_socket_params =
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<const scoped_refptr<SSLSocketParams>*>(socket_params);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.RequestSocket(group_name, *casted_socket_params, priority,
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             handle, callback, net_log);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientSocketPool::RequestSockets(
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& group_name,
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const void* params,
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int num_sockets,
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const BoundNetLog& net_log) {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_refptr<SSLSocketParams>* casted_params =
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<const scoped_refptr<SSLSocketParams>*>(params);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientSocketPool::CancelRequest(const std::string& group_name,
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        ClientSocketHandle* handle) {
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base_.CancelRequest(group_name, handle);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientSocketPool::ReleaseSocket(const std::string& group_name,
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        StreamSocket* socket, int id) {
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base_.ReleaseSocket(group_name, socket, id);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SSLClientSocketPool::FlushWithError(int error) {
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base_.FlushWithError(error);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SSLClientSocketPool::IsStalled() const {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.IsStalled() ||
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (transport_pool_ && transport_pool_->IsStalled()) ||
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (socks_pool_ && socks_pool_->IsStalled()) ||
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (http_proxy_pool_ && http_proxy_pool_->IsStalled());
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientSocketPool::CloseIdleSockets() {
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base_.CloseIdleSockets();
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLClientSocketPool::IdleSocketCount() const {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.idle_socket_count();
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLClientSocketPool::IdleSocketCountInGroup(
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& group_name) const {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.IdleSocketCountInGroup(group_name);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadState SSLClientSocketPool::GetLoadState(
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& group_name, const ClientSocketHandle* handle) const {
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.GetLoadState(group_name, handle);
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientSocketPool::AddLayeredPool(LayeredPool* layered_pool) {
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base_.AddLayeredPool(layered_pool);
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientSocketPool::RemoveLayeredPool(LayeredPool* layered_pool) {
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base_.RemoveLayeredPool(layered_pool);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::DictionaryValue* SSLClientSocketPool::GetInfoAsValue(
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& name,
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& type,
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool include_nested_pools) const {
6207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::DictionaryValue* dict = base_.GetInfoAsValue(name, type);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (include_nested_pools) {
6227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::ListValue* list = new base::ListValue();
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (transport_pool_) {
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      list->Append(transport_pool_->GetInfoAsValue("transport_socket_pool",
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   "transport_socket_pool",
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   false));
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (socks_pool_) {
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      list->Append(socks_pool_->GetInfoAsValue("socks_pool",
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               "socks_pool",
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               true));
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (http_proxy_pool_) {
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      list->Append(http_proxy_pool_->GetInfoAsValue("http_proxy_pool",
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    "http_proxy_pool",
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    true));
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dict->Set("nested_pools", list);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dict;
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta SSLClientSocketPool::ConnectionTimeout() const {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.ConnectionTimeout();
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ClientSocketPoolHistograms* SSLClientSocketPool::histograms() const {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.histograms();
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientSocketPool::OnSSLConfigChanged() {
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FlushWithError(ERR_NETWORK_CHANGED);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SSLClientSocketPool::CloseOneIdleConnection() {
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base_.CloseOneIdleSocket())
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.CloseOneIdleConnectionInLayeredPool();
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
662