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"
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/stl_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/host_port_pair.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_proxy_client_socket.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_proxy_client_socket_pool.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_factory.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_handle.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/socks_client_socket_pool.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/transport_client_socket_pool.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_cert_request_info.h"
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/ssl/ssl_connection_status_flags.h"
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/ssl/ssl_info.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLSocketParams::SSLSocketParams(
303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const scoped_refptr<TransportSocketParams>& direct_params,
313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const scoped_refptr<SOCKSSocketParams>& socks_proxy_params,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<HttpProxySocketParams>& http_proxy_params,
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)
393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    : direct_params_(direct_params),
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      socks_proxy_params_(socks_proxy_params),
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_proxy_params_(http_proxy_params),
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_and_port_(host_and_port),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ssl_config_(ssl_config),
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      privacy_mode_(privacy_mode),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      load_flags_(load_flags),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      force_spdy_over_ssl_(force_spdy_over_ssl),
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      want_spdy_over_npn_(want_spdy_over_npn),
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ignore_limits_(false) {
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (direct_params_.get()) {
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(!socks_proxy_params_.get());
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(!http_proxy_params_.get());
523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ignore_limits_ = direct_params_->ignore_limits();
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else if (socks_proxy_params_.get()) {
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(!http_proxy_params_.get());
553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ignore_limits_ = socks_proxy_params_->ignore_limits();
563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else {
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(http_proxy_params_.get());
583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ignore_limits_ = http_proxy_params_->ignore_limits();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLSocketParams::~SSLSocketParams() {}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SSLSocketParams::ConnectionType SSLSocketParams::GetConnectionType() const {
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (direct_params_.get()) {
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(!socks_proxy_params_.get());
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(!http_proxy_params_.get());
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return DIRECT;
693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (socks_proxy_params_.get()) {
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(!http_proxy_params_.get());
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return SOCKS_PROXY;
743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(http_proxy_params_.get());
773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return HTTP_PROXY;
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const scoped_refptr<TransportSocketParams>&
813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SSLSocketParams::GetDirectConnectionParams() const {
823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(GetConnectionType(), DIRECT);
833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return direct_params_;
843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const scoped_refptr<SOCKSSocketParams>&
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SSLSocketParams::GetSocksProxyConnectionParams() const {
883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(GetConnectionType(), SOCKS_PROXY);
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return socks_proxy_params_;
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const scoped_refptr<HttpProxySocketParams>&
933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SSLSocketParams::GetHttpProxyConnectionParams() const {
943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(GetConnectionType(), HTTP_PROXY);
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return http_proxy_params_;
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SSLConnectJobMessenger::SocketAndCallback::SocketAndCallback(
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    SSLClientSocket* ssl_socket,
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::Closure& job_resumption_callback)
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : socket(ssl_socket), callback(job_resumption_callback) {
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SSLConnectJobMessenger::SocketAndCallback::~SocketAndCallback() {
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)SSLConnectJobMessenger::SSLConnectJobMessenger(
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const base::Closure& messenger_finished_callback)
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : messenger_finished_callback_(messenger_finished_callback),
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      weak_factory_(this) {
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SSLConnectJobMessenger::~SSLConnectJobMessenger() {
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SSLConnectJobMessenger::RemovePendingSocket(SSLClientSocket* ssl_socket) {
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Sockets do not need to be removed from connecting_sockets_ because
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // OnSSLHandshakeCompleted will do this.
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (SSLPendingSocketsAndCallbacks::iterator it =
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           pending_sockets_and_callbacks_.begin();
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       it != pending_sockets_and_callbacks_.end();
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       ++it) {
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (it->socket == ssl_socket) {
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      pending_sockets_and_callbacks_.erase(it);
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return;
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool SSLConnectJobMessenger::CanProceed(SSLClientSocket* ssl_socket) {
13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // If there are no connecting sockets, allow the connection to proceed.
13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return connecting_sockets_.empty();
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SSLConnectJobMessenger::MonitorConnectionResult(
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    SSLClientSocket* ssl_socket) {
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  connecting_sockets_.push_back(ssl_socket);
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ssl_socket->SetHandshakeCompletionCallback(
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&SSLConnectJobMessenger::OnSSLHandshakeCompleted,
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SSLConnectJobMessenger::AddPendingSocket(SSLClientSocket* ssl_socket,
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                              const base::Closure& callback) {
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(!connecting_sockets_.empty());
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  pending_sockets_and_callbacks_.push_back(
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      SocketAndCallback(ssl_socket, callback));
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SSLConnectJobMessenger::OnSSLHandshakeCompleted() {
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  connecting_sockets_.clear();
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SSLPendingSocketsAndCallbacks temp_list;
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  temp_list.swap(pending_sockets_and_callbacks_);
15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::Closure messenger_finished_callback = messenger_finished_callback_;
15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  messenger_finished_callback.Run();
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RunAllCallbacks(temp_list);
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SSLConnectJobMessenger::RunAllCallbacks(
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const SSLPendingSocketsAndCallbacks& pending_sockets_and_callbacks) {
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (std::vector<SocketAndCallback>::const_iterator it =
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           pending_sockets_and_callbacks.begin();
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       it != pending_sockets_and_callbacks.end();
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       ++it) {
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    it->callback.Run();
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Timeout for the SSL handshake portion of the connect.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSSLHandshakeTimeoutInSeconds = 30;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLConnectJob::SSLConnectJob(const std::string& group_name,
1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             RequestPriority priority,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const scoped_refptr<SSLSocketParams>& params,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const base::TimeDelta& timeout_duration,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             TransportClientSocketPool* transport_pool,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             SOCKSClientSocketPool* socks_pool,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             HttpProxyClientSocketPool* http_proxy_pool,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ClientSocketFactory* client_socket_factory,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             HostResolver* host_resolver,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const SSLClientSocketContext& context,
18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                             const GetMessengerCallback& get_messenger_callback,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             Delegate* delegate,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             NetLog* net_log)
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    : ConnectJob(group_name,
1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 timeout_duration,
1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                 priority,
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 delegate,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params_(params),
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transport_pool_(transport_pool),
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socks_pool_(socks_pool),
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_proxy_pool_(http_proxy_pool),
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_socket_factory_(client_socket_factory),
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_resolver_(host_resolver),
1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      context_(context.cert_verifier,
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               context.channel_id_service,
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch               context.transport_security_state,
199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               context.cert_transparency_verifier,
200e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch               (params->privacy_mode() == PRIVACY_MODE_ENABLED
2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    ? "pm/" + context.ssl_session_cache_shard
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    : context.ssl_session_cache_shard)),
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      io_callback_(
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          base::Bind(&SSLConnectJob::OnIOComplete, base::Unretained(this))),
20503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      messenger_(NULL),
20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      get_messenger_callback_(get_messenger_callback),
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      weak_factory_(this) {
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SSLConnectJob::~SSLConnectJob() {
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (ssl_socket_.get() && messenger_)
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    messenger_->RemovePendingSocket(ssl_socket_.get());
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadState SSLConnectJob::GetLoadState() const {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (next_state_) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_TUNNEL_CONNECT_COMPLETE:
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (transport_socket_handle_->socket())
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // else, fall through.
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_TRANSPORT_CONNECT:
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_TRANSPORT_CONNECT_COMPLETE:
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_SOCKS_CONNECT:
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_SOCKS_CONNECT_COMPLETE:
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_TUNNEL_CONNECT:
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return transport_socket_handle_->GetLoadState();
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case STATE_CREATE_SSL_SOCKET:
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case STATE_CHECK_FOR_RESUME:
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_SSL_CONNECT:
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case STATE_SSL_CONNECT_COMPLETE:
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return LOAD_STATE_SSL_HANDSHAKE;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return LOAD_STATE_IDLE;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLConnectJob::GetAdditionalErrorState(ClientSocketHandle* handle) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Headers in |error_response_info_| indicate a proxy tunnel setup
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // problem. See DoTunnelConnectComplete.
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (error_response_info_.headers.get()) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handle->set_pending_http_proxy_connection(
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        transport_socket_handle_.release());
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle->set_ssl_error_response_info(error_response_info_);
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!connect_timing_.ssl_start.is_null())
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handle->set_is_ssl_error(true);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLConnectJob::OnIOComplete(int result) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = DoLoop(result);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv != ERR_IO_PENDING)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyDelegateOfCompletion(rv);  // Deletes |this|.
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoLoop(int result) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(next_state_, STATE_NONE);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = result;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state = next_state_;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    next_state_ = STATE_NONE;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (state) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_TRANSPORT_CONNECT:
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_EQ(OK, rv);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoTransportConnect();
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_TRANSPORT_CONNECT_COMPLETE:
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoTransportConnectComplete(rv);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_SOCKS_CONNECT:
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_EQ(OK, rv);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoSOCKSConnect();
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_SOCKS_CONNECT_COMPLETE:
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoSOCKSConnectComplete(rv);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_TUNNEL_CONNECT:
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_EQ(OK, rv);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoTunnelConnect();
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_TUNNEL_CONNECT_COMPLETE:
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoTunnelConnectComplete(rv);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      case STATE_CREATE_SSL_SOCKET:
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        rv = DoCreateSSLSocket();
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        break;
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      case STATE_CHECK_FOR_RESUME:
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        rv = DoCheckForResume();
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        break;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_SSL_CONNECT:
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_EQ(OK, rv);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoSSLConnect();
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case STATE_SSL_CONNECT_COMPLETE:
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = DoSSLConnectComplete(rv);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED() << "bad state";
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ERR_FAILED;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rv;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoTransportConnect() {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(transport_pool_);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transport_socket_handle_.reset(new ClientSocketHandle());
3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<TransportSocketParams> direct_params =
3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      params_->GetDirectConnectionParams();
3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return transport_socket_handle_->Init(group_name(),
3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        direct_params,
3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        priority(),
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                        io_callback_,
3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        transport_pool_,
3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        net_log());
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoTransportConnectComplete(int result) {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == OK)
3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    next_state_ = STATE_CREATE_SSL_SOCKET;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoSOCKSConnect() {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(socks_pool_);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_SOCKS_CONNECT_COMPLETE;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transport_socket_handle_.reset(new ClientSocketHandle());
3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<SOCKSSocketParams> socks_proxy_params =
3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      params_->GetSocksProxyConnectionParams();
3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return transport_socket_handle_->Init(group_name(),
3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        socks_proxy_params,
3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        priority(),
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                        io_callback_,
3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        socks_pool_,
3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        net_log());
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoSOCKSConnectComplete(int result) {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == OK)
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    next_state_ = STATE_CREATE_SSL_SOCKET;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoTunnelConnect() {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(http_proxy_pool_);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_state_ = STATE_TUNNEL_CONNECT_COMPLETE;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transport_socket_handle_.reset(new ClientSocketHandle());
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpProxySocketParams> http_proxy_params =
3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      params_->GetHttpProxyConnectionParams();
3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return transport_socket_handle_->Init(group_name(),
3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        http_proxy_params,
3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        priority(),
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                        io_callback_,
3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        http_proxy_pool_,
3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        net_log());
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoTunnelConnectComplete(int result) {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Extract the information needed to prompt for appropriate proxy
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // authentication so that when ClientSocketPoolBaseHelper calls
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |GetAdditionalErrorState|, we can easily set the state.
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_response_info_ = transport_socket_handle_->ssl_error_response_info();
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (result == ERR_PROXY_AUTH_REQUESTED ||
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StreamSocket* socket = transport_socket_handle_->socket();
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpProxyClientSocket* tunnel_socket =
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<HttpProxyClientSocket*>(socket);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_response_info_ = *tunnel_socket->GetConnectResponseInfo();
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result < 0)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  next_state_ = STATE_CREATE_SSL_SOCKET;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int SSLConnectJob::DoCreateSSLSocket() {
3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  next_state_ = STATE_CHECK_FOR_RESUME;
3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset the timeout to just the time allowed for the SSL handshake.
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResetTimer(base::TimeDelta::FromSeconds(kSSLHandshakeTimeoutInSeconds));
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the handle has a fresh socket, get its connect start and DNS times.
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should always be the case.
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const LoadTimingInfo::ConnectTiming& socket_connect_timing =
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      transport_socket_handle_->connect_timing();
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!transport_socket_handle_->is_reused() &&
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !socket_connect_timing.connect_start.is_null()) {
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Overwriting |connect_start| serves two purposes - it adjusts timing so
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // |connect_start| doesn't include dns times, and it adjusts the time so
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // as not to include time spent waiting for an idle socket.
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    connect_timing_.connect_start = socket_connect_timing.connect_start;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    connect_timing_.dns_start = socket_connect_timing.dns_start;
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    connect_timing_.dns_end = socket_connect_timing.dns_end;
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_socket_ = client_socket_factory_->CreateSSLClientSocket(
4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      transport_socket_handle_.Pass(),
4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      params_->host_and_port(),
4087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      params_->ssl_config(),
4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      context_);
41003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
41103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!ssl_socket_->InSessionCache())
41203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    messenger_ = get_messenger_callback_.Run(ssl_socket_->GetSessionCacheKey());
41303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return OK;
4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int SSLConnectJob::DoCheckForResume() {
4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  next_state_ = STATE_SSL_CONNECT;
41903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!messenger_)
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return OK;
4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (messenger_->CanProceed(ssl_socket_.get())) {
42403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    messenger_->MonitorConnectionResult(ssl_socket_.get());
42503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // The SSLConnectJob no longer needs access to the messenger after this
42603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // point.
42703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    messenger_ = NULL;
4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return OK;
4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
43003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  messenger_->AddPendingSocket(ssl_socket_.get(),
4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               base::Bind(&SSLConnectJob::ResumeSSLConnection,
4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                          weak_factory_.GetWeakPtr()));
43403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return ERR_IO_PENDING;
4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int SSLConnectJob::DoSSLConnect() {
4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  next_state_ = STATE_SSL_CONNECT_COMPLETE;
4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  connect_timing_.ssl_start = base::TimeTicks::Now();
4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return ssl_socket_->Connect(io_callback_);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLConnectJob::DoSSLConnectComplete(int result) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  connect_timing_.ssl_end = base::TimeTicks::Now();
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLClientSocket::NextProtoStatus status =
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SSLClientSocket::kNextProtoUnsupported;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string proto;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that hasn't had SSL_ImportFD called on it. If we get a certificate error
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // here, then we know that we called SSL_ImportFD.
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == OK || IsCertificateError(result))
4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    status = ssl_socket_->GetNextProto(&proto);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we want spdy over npn, make sure it succeeded.
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status == SSLClientSocket::kNextProtoNegotiated) {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_socket_->set_was_npn_negotiated(true);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NextProto protocol_negotiated =
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SSLClientSocket::NextProtoFromString(proto);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_socket_->set_protocol_negotiated(protocol_negotiated);
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If we negotiated a SPDY version, it must have been present in
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // SSLConfig::next_protos.
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(mbelshe): Verify this.
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (protocol_negotiated >= kProtoSPDYMinimumVersion &&
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        protocol_negotiated <= kProtoSPDYMaximumVersion) {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ssl_socket_->set_was_spdy_negotiated(true);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params_->want_spdy_over_npn() && !ssl_socket_->was_spdy_negotiated())
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_NPN_NEGOTIATION_FAILED;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Spdy might be turned on by default, or it might be over npn.
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool using_spdy = params_->force_spdy_over_ssl() ||
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      params_->want_spdy_over_npn();
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == OK ||
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ssl_socket_->IgnoreCertError(result, params_->load_flags())) {
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!connect_timing_.ssl_start.is_null());
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta connect_duration =
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        connect_timing_.ssl_end - connect_timing_.ssl_start;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (using_spdy) {
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UMA_HISTOGRAM_CUSTOM_TIMES("Net.SpdyConnectionLatency_2",
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 connect_duration,
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::TimeDelta::FromMilliseconds(1),
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 base::TimeDelta::FromMinutes(1),
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 100);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_2",
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               connect_duration,
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base::TimeDelta::FromMilliseconds(1),
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               base::TimeDelta::FromMinutes(1),
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               100);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSLInfo ssl_info;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_socket_->GetSSLInfo(&ssl_info);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_CipherSuite",
502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                SSLConnectionStatusToCipherSuite(
503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                    ssl_info.connection_status));
504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    UMA_HISTOGRAM_BOOLEAN(
5061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "Net.RenegotiationExtensionSupported",
5071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        (ssl_info.connection_status &
5081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION) == 0);
5091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME) {
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Resume_Handshake",
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 connect_duration,
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::TimeDelta::FromMilliseconds(1),
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::TimeDelta::FromMinutes(1),
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 100);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_FULL) {
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Full_Handshake",
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 connect_duration,
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::TimeDelta::FromMilliseconds(1),
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::TimeDelta::FromMinutes(1),
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 100);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& host = params_->host_and_port().host();
5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool is_google =
5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        host == "google.com" ||
5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        (host.size() > 11 && host.rfind(".google.com") == host.size() - 11);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_google) {
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google2",
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 connect_duration,
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::TimeDelta::FromMilliseconds(1),
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 base::TimeDelta::FromMinutes(1),
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 100);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME) {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google_"
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       "Resume_Handshake",
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   connect_duration,
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   base::TimeDelta::FromMilliseconds(1),
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   base::TimeDelta::FromMinutes(1),
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   100);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_FULL) {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google_"
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       "Full_Handshake",
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   connect_duration,
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   base::TimeDelta::FromMilliseconds(1),
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   base::TimeDelta::FromMinutes(1),
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   100);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == OK || IsCertificateError(result)) {
5533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    SetSocket(ssl_socket_.PassAs<StreamSocket>());
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_response_info_.cert_request_info = new SSLCertRequestInfo;
556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ssl_socket_->GetSSLCertRequestInfo(
557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        error_response_info_.cert_request_info.get());
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SSLConnectJob::ResumeSSLConnection() {
5645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_EQ(next_state_, STATE_SSL_CONNECT);
56503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  messenger_ = NULL;
5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnIOComplete(OK);
5675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SSLConnectJob::State SSLConnectJob::GetInitialState(
5703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    SSLSocketParams::ConnectionType connection_type) {
5713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  switch (connection_type) {
5723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case SSLSocketParams::DIRECT:
5733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return STATE_TRANSPORT_CONNECT;
5743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case SSLSocketParams::HTTP_PROXY:
5753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return STATE_TUNNEL_CONNECT;
5763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case SSLSocketParams::SOCKS_PROXY:
5773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return STATE_SOCKS_CONNECT;
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  NOTREACHED();
5803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return STATE_NONE;
5813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int SSLConnectJob::ConnectInternal() {
5843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  next_state_ = GetInitialState(params_->GetConnectionType());
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return DoLoop(OK);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLClientSocketPool::SSLConnectJobFactory::SSLConnectJobFactory(
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TransportClientSocketPool* transport_pool,
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SOCKSClientSocketPool* socks_pool,
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpProxyClientSocketPool* http_proxy_pool,
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClientSocketFactory* client_socket_factory,
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SSLClientSocketContext& context,
59503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const SSLConnectJob::GetMessengerCallback& get_messenger_callback,
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetLog* net_log)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : transport_pool_(transport_pool),
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socks_pool_(socks_pool),
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_proxy_pool_(http_proxy_pool),
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_socket_factory_(client_socket_factory),
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_resolver_(host_resolver),
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_(context),
60303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      get_messenger_callback_(get_messenger_callback),
60403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      net_log_(net_log) {
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta max_transport_timeout = base::TimeDelta();
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta pool_timeout;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (transport_pool_)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    max_transport_timeout = transport_pool_->ConnectionTimeout();
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (socks_pool_) {
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pool_timeout = socks_pool_->ConnectionTimeout();
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pool_timeout > max_transport_timeout)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_transport_timeout = pool_timeout;
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (http_proxy_pool_) {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pool_timeout = http_proxy_pool_->ConnectionTimeout();
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pool_timeout > max_transport_timeout)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_transport_timeout = pool_timeout;
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  timeout_ = max_transport_timeout +
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromSeconds(kSSLHandshakeTimeoutInSeconds);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SSLClientSocketPool::SSLConnectJobFactory::~SSLConnectJobFactory() {
6245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
6255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLClientSocketPool::SSLClientSocketPool(
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int max_sockets,
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int max_sockets_per_group,
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClientSocketPoolHistograms* histograms,
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* cert_verifier,
6325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ChannelIDService* channel_id_service,
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TransportSecurityState* transport_security_state,
634a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    CTVerifier* cert_transparency_verifier,
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& ssl_session_cache_shard,
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClientSocketFactory* client_socket_factory,
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TransportClientSocketPool* transport_pool,
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SOCKSClientSocketPool* socks_pool,
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpProxyClientSocketPool* http_proxy_pool,
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSLConfigService* ssl_config_service,
6415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool enable_ssl_connect_job_waiting,
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetLog* net_log)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : transport_pool_(transport_pool),
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      socks_pool_(socks_pool),
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_proxy_pool_(http_proxy_pool),
6465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base_(this,
6475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            max_sockets,
6485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            max_sockets_per_group,
6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            histograms,
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ClientSocketPool::unused_idle_socket_timeout(),
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ClientSocketPool::used_idle_socket_timeout(),
6525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            new SSLConnectJobFactory(
6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                transport_pool,
6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                socks_pool,
6555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                http_proxy_pool,
6565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                client_socket_factory,
6575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                host_resolver,
6585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                SSLClientSocketContext(cert_verifier,
6595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       channel_id_service,
6605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       transport_security_state,
6615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       cert_transparency_verifier,
6625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       ssl_session_cache_shard),
66303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                base::Bind(
66403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                    &SSLClientSocketPool::GetOrCreateSSLConnectJobMessenger,
66503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                    base::Unretained(this)),
6665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                net_log)),
66703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ssl_config_service_(ssl_config_service),
66803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      enable_ssl_connect_job_waiting_(enable_ssl_connect_job_waiting) {
669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (ssl_config_service_.get())
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_config_service_->AddObserver(this);
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (transport_pool_)
6723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base_.AddLowerLayeredPool(transport_pool_);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (socks_pool_)
6743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base_.AddLowerLayeredPool(socks_pool_);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (http_proxy_pool_)
6763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base_.AddLowerLayeredPool(http_proxy_pool_);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLClientSocketPool::~SSLClientSocketPool() {
68003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  STLDeleteContainerPairSecondPointers(messenger_map_.begin(),
68103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       messenger_map_.end());
682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (ssl_config_service_.get())
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_config_service_->RemoveObserver(this);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_ptr<ConnectJob> SSLClientSocketPool::SSLConnectJobFactory::NewConnectJob(
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& group_name,
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PoolBase::Request& request,
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConnectJob::Delegate* delegate) const {
6905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return scoped_ptr<ConnectJob>(new SSLConnectJob(group_name,
6915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  request.priority(),
6925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  request.params(),
6935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  ConnectionTimeout(),
6945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  transport_pool_,
6955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  socks_pool_,
6965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  http_proxy_pool_,
6975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  client_socket_factory_,
6985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  host_resolver_,
6995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  context_,
70003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                                  get_messenger_callback_,
7015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  delegate,
7025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  net_log_));
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)base::TimeDelta SSLClientSocketPool::SSLConnectJobFactory::ConnectionTimeout()
70603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const {
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return timeout_;
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLClientSocketPool::RequestSocket(const std::string& group_name,
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const void* socket_params,
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       RequestPriority priority,
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       ClientSocketHandle* handle,
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const CompletionCallback& callback,
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const BoundNetLog& net_log) {
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_refptr<SSLSocketParams>* casted_socket_params =
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<const scoped_refptr<SSLSocketParams>*>(socket_params);
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.RequestSocket(group_name, *casted_socket_params, priority,
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             handle, callback, net_log);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientSocketPool::RequestSockets(
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& group_name,
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const void* params,
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int num_sockets,
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const BoundNetLog& net_log) {
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_refptr<SSLSocketParams>* casted_params =
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<const scoped_refptr<SSLSocketParams>*>(params);
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientSocketPool::CancelRequest(const std::string& group_name,
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        ClientSocketHandle* handle) {
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base_.CancelRequest(group_name, handle);
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientSocketPool::ReleaseSocket(const std::string& group_name,
7403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        scoped_ptr<StreamSocket> socket,
7413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        int id) {
7423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base_.ReleaseSocket(group_name, socket.Pass(), id);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SSLClientSocketPool::FlushWithError(int error) {
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base_.FlushWithError(error);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientSocketPool::CloseIdleSockets() {
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base_.CloseIdleSockets();
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLClientSocketPool::IdleSocketCount() const {
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.idle_socket_count();
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SSLClientSocketPool::IdleSocketCountInGroup(
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& group_name) const {
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.IdleSocketCountInGroup(group_name);
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadState SSLClientSocketPool::GetLoadState(
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& group_name, const ClientSocketHandle* handle) const {
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.GetLoadState(group_name, handle);
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::DictionaryValue* SSLClientSocketPool::GetInfoAsValue(
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& name,
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& type,
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool include_nested_pools) const {
7717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::DictionaryValue* dict = base_.GetInfoAsValue(name, type);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (include_nested_pools) {
7737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::ListValue* list = new base::ListValue();
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (transport_pool_) {
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      list->Append(transport_pool_->GetInfoAsValue("transport_socket_pool",
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   "transport_socket_pool",
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   false));
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (socks_pool_) {
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      list->Append(socks_pool_->GetInfoAsValue("socks_pool",
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               "socks_pool",
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               true));
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (http_proxy_pool_) {
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      list->Append(http_proxy_pool_->GetInfoAsValue("http_proxy_pool",
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    "http_proxy_pool",
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    true));
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dict->Set("nested_pools", list);
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dict;
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta SSLClientSocketPool::ConnectionTimeout() const {
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.ConnectionTimeout();
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ClientSocketPoolHistograms* SSLClientSocketPool::histograms() const {
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_.histograms();
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool SSLClientSocketPool::IsStalled() const {
8033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return base_.IsStalled();
8043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
8053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SSLClientSocketPool::AddHigherLayeredPool(HigherLayeredPool* higher_pool) {
8073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base_.AddHigherLayeredPool(higher_pool);
8083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
8093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SSLClientSocketPool::RemoveHigherLayeredPool(
8113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    HigherLayeredPool* higher_pool) {
8123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base_.RemoveHigherLayeredPool(higher_pool);
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SSLClientSocketPool::CloseOneIdleConnection() {
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base_.CloseOneIdleSocket())
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
8183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return base_.CloseOneIdleConnectionInHigherLayeredPool();
8193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
8203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
82103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)SSLConnectJobMessenger* SSLClientSocketPool::GetOrCreateSSLConnectJobMessenger(
82203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const std::string& cache_key) {
82303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!enable_ssl_connect_job_waiting_)
82403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return NULL;
82503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  MessengerMap::const_iterator it = messenger_map_.find(cache_key);
82603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (it == messenger_map_.end()) {
82703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::pair<MessengerMap::iterator, bool> iter =
82803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        messenger_map_.insert(MessengerMap::value_type(
82903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            cache_key,
83003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            new SSLConnectJobMessenger(
83103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                base::Bind(&SSLClientSocketPool::DeleteSSLConnectJobMessenger,
83203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                           base::Unretained(this),
83303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                           cache_key))));
83403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    it = iter.first;
83503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
83603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return it->second;
83703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
83803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
83903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void SSLClientSocketPool::DeleteSSLConnectJobMessenger(
84003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const std::string& cache_key) {
84103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  MessengerMap::iterator it = messenger_map_.find(cache_key);
84203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  CHECK(it != messenger_map_.end());
84303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  delete it->second;
84403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  messenger_map_.erase(it);
84503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
84603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SSLClientSocketPool::OnSSLConfigChanged() {
8483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FlushWithError(ERR_NETWORK_CHANGED);
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
852