| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/socket/ssl_client_socket_pool.h" |
| |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/metrics/field_trial.h" |
| #include "base/metrics/histogram_macros.h" |
| #include "base/metrics/sparse_histogram.h" |
| #include "base/profiler/scoped_tracker.h" |
| #include "base/values.h" |
| #include "net/base/host_port_pair.h" |
| #include "net/base/net_errors.h" |
| #include "net/http/http_proxy_client_socket.h" |
| #include "net/http/http_proxy_client_socket_pool.h" |
| #include "net/socket/client_socket_factory.h" |
| #include "net/socket/client_socket_handle.h" |
| #include "net/socket/socks_client_socket_pool.h" |
| #include "net/socket/ssl_client_socket.h" |
| #include "net/socket/transport_client_socket_pool.h" |
| #include "net/ssl/ssl_cert_request_info.h" |
| #include "net/ssl/ssl_cipher_suite_names.h" |
| #include "net/ssl/ssl_connection_status_flags.h" |
| #include "net/ssl/ssl_info.h" |
| |
| namespace net { |
| |
| SSLSocketParams::SSLSocketParams( |
| const scoped_refptr<TransportSocketParams>& direct_params, |
| const scoped_refptr<SOCKSSocketParams>& socks_proxy_params, |
| const scoped_refptr<HttpProxySocketParams>& http_proxy_params, |
| const HostPortPair& host_and_port, |
| const SSLConfig& ssl_config, |
| PrivacyMode privacy_mode, |
| int load_flags, |
| bool expect_spdy) |
| : direct_params_(direct_params), |
| socks_proxy_params_(socks_proxy_params), |
| http_proxy_params_(http_proxy_params), |
| host_and_port_(host_and_port), |
| ssl_config_(ssl_config), |
| privacy_mode_(privacy_mode), |
| load_flags_(load_flags), |
| expect_spdy_(expect_spdy), |
| ignore_limits_(false) { |
| if (direct_params_.get()) { |
| DCHECK(!socks_proxy_params_.get()); |
| DCHECK(!http_proxy_params_.get()); |
| ignore_limits_ = direct_params_->ignore_limits(); |
| } else if (socks_proxy_params_.get()) { |
| DCHECK(!http_proxy_params_.get()); |
| ignore_limits_ = socks_proxy_params_->ignore_limits(); |
| } else { |
| DCHECK(http_proxy_params_.get()); |
| ignore_limits_ = http_proxy_params_->ignore_limits(); |
| } |
| } |
| |
| SSLSocketParams::~SSLSocketParams() {} |
| |
| SSLSocketParams::ConnectionType SSLSocketParams::GetConnectionType() const { |
| if (direct_params_.get()) { |
| DCHECK(!socks_proxy_params_.get()); |
| DCHECK(!http_proxy_params_.get()); |
| return DIRECT; |
| } |
| |
| if (socks_proxy_params_.get()) { |
| DCHECK(!http_proxy_params_.get()); |
| return SOCKS_PROXY; |
| } |
| |
| DCHECK(http_proxy_params_.get()); |
| return HTTP_PROXY; |
| } |
| |
| const scoped_refptr<TransportSocketParams>& |
| SSLSocketParams::GetDirectConnectionParams() const { |
| DCHECK_EQ(GetConnectionType(), DIRECT); |
| return direct_params_; |
| } |
| |
| const scoped_refptr<SOCKSSocketParams>& |
| SSLSocketParams::GetSocksProxyConnectionParams() const { |
| DCHECK_EQ(GetConnectionType(), SOCKS_PROXY); |
| return socks_proxy_params_; |
| } |
| |
| const scoped_refptr<HttpProxySocketParams>& |
| SSLSocketParams::GetHttpProxyConnectionParams() const { |
| DCHECK_EQ(GetConnectionType(), HTTP_PROXY); |
| return http_proxy_params_; |
| } |
| |
| // Timeout for the SSL handshake portion of the connect. |
| static const int kSSLHandshakeTimeoutInSeconds = 30; |
| |
| SSLConnectJob::SSLConnectJob(const std::string& group_name, |
| RequestPriority priority, |
| const scoped_refptr<SSLSocketParams>& params, |
| const base::TimeDelta& timeout_duration, |
| TransportClientSocketPool* transport_pool, |
| SOCKSClientSocketPool* socks_pool, |
| HttpProxyClientSocketPool* http_proxy_pool, |
| ClientSocketFactory* client_socket_factory, |
| const SSLClientSocketContext& context, |
| Delegate* delegate, |
| NetLog* net_log) |
| : ConnectJob(group_name, |
| timeout_duration, |
| priority, |
| delegate, |
| BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)), |
| params_(params), |
| transport_pool_(transport_pool), |
| socks_pool_(socks_pool), |
| http_proxy_pool_(http_proxy_pool), |
| client_socket_factory_(client_socket_factory), |
| context_(context.cert_verifier, |
| context.channel_id_service, |
| context.transport_security_state, |
| context.cert_transparency_verifier, |
| context.cert_policy_enforcer, |
| (params->privacy_mode() == PRIVACY_MODE_ENABLED |
| ? "pm/" + context.ssl_session_cache_shard |
| : context.ssl_session_cache_shard)), |
| callback_( |
| base::Bind(&SSLConnectJob::OnIOComplete, base::Unretained(this))) { |
| } |
| |
| SSLConnectJob::~SSLConnectJob() { |
| } |
| |
| LoadState SSLConnectJob::GetLoadState() const { |
| switch (next_state_) { |
| case STATE_TUNNEL_CONNECT_COMPLETE: |
| if (transport_socket_handle_->socket()) |
| return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL; |
| // else, fall through. |
| case STATE_TRANSPORT_CONNECT: |
| case STATE_TRANSPORT_CONNECT_COMPLETE: |
| case STATE_SOCKS_CONNECT: |
| case STATE_SOCKS_CONNECT_COMPLETE: |
| case STATE_TUNNEL_CONNECT: |
| return transport_socket_handle_->GetLoadState(); |
| case STATE_SSL_CONNECT: |
| case STATE_SSL_CONNECT_COMPLETE: |
| return LOAD_STATE_SSL_HANDSHAKE; |
| default: |
| NOTREACHED(); |
| return LOAD_STATE_IDLE; |
| } |
| } |
| |
| void SSLConnectJob::GetAdditionalErrorState(ClientSocketHandle* handle) { |
| // Headers in |error_response_info_| indicate a proxy tunnel setup |
| // problem. See DoTunnelConnectComplete. |
| if (error_response_info_.headers.get()) { |
| handle->set_pending_http_proxy_connection( |
| transport_socket_handle_.release()); |
| } |
| handle->set_ssl_error_response_info(error_response_info_); |
| if (!connect_timing_.ssl_start.is_null()) |
| handle->set_is_ssl_error(true); |
| if (ssl_socket_) |
| handle->set_ssl_failure_state(ssl_socket_->GetSSLFailureState()); |
| |
| handle->set_connection_attempts(connection_attempts_); |
| } |
| |
| void SSLConnectJob::OnIOComplete(int result) { |
| int rv = DoLoop(result); |
| if (rv != ERR_IO_PENDING) |
| NotifyDelegateOfCompletion(rv); // Deletes |this|. |
| } |
| |
| int SSLConnectJob::DoLoop(int result) { |
| DCHECK_NE(next_state_, STATE_NONE); |
| |
| int rv = result; |
| do { |
| State state = next_state_; |
| next_state_ = STATE_NONE; |
| switch (state) { |
| case STATE_TRANSPORT_CONNECT: |
| DCHECK_EQ(OK, rv); |
| rv = DoTransportConnect(); |
| break; |
| case STATE_TRANSPORT_CONNECT_COMPLETE: |
| rv = DoTransportConnectComplete(rv); |
| break; |
| case STATE_SOCKS_CONNECT: |
| DCHECK_EQ(OK, rv); |
| rv = DoSOCKSConnect(); |
| break; |
| case STATE_SOCKS_CONNECT_COMPLETE: |
| rv = DoSOCKSConnectComplete(rv); |
| break; |
| case STATE_TUNNEL_CONNECT: |
| DCHECK_EQ(OK, rv); |
| rv = DoTunnelConnect(); |
| break; |
| case STATE_TUNNEL_CONNECT_COMPLETE: |
| rv = DoTunnelConnectComplete(rv); |
| break; |
| case STATE_SSL_CONNECT: |
| DCHECK_EQ(OK, rv); |
| rv = DoSSLConnect(); |
| break; |
| case STATE_SSL_CONNECT_COMPLETE: |
| rv = DoSSLConnectComplete(rv); |
| break; |
| default: |
| NOTREACHED() << "bad state"; |
| rv = ERR_FAILED; |
| break; |
| } |
| } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
| |
| return rv; |
| } |
| |
| int SSLConnectJob::DoTransportConnect() { |
| DCHECK(transport_pool_); |
| |
| next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE; |
| transport_socket_handle_.reset(new ClientSocketHandle()); |
| scoped_refptr<TransportSocketParams> direct_params = |
| params_->GetDirectConnectionParams(); |
| return transport_socket_handle_->Init(group_name(), direct_params, priority(), |
| callback_, transport_pool_, net_log()); |
| } |
| |
| int SSLConnectJob::DoTransportConnectComplete(int result) { |
| connection_attempts_ = transport_socket_handle_->connection_attempts(); |
| if (result == OK) { |
| next_state_ = STATE_SSL_CONNECT; |
| transport_socket_handle_->socket()->GetPeerAddress(&server_address_); |
| } |
| |
| return result; |
| } |
| |
| int SSLConnectJob::DoSOCKSConnect() { |
| DCHECK(socks_pool_); |
| next_state_ = STATE_SOCKS_CONNECT_COMPLETE; |
| transport_socket_handle_.reset(new ClientSocketHandle()); |
| scoped_refptr<SOCKSSocketParams> socks_proxy_params = |
| params_->GetSocksProxyConnectionParams(); |
| return transport_socket_handle_->Init(group_name(), socks_proxy_params, |
| priority(), callback_, socks_pool_, |
| net_log()); |
| } |
| |
| int SSLConnectJob::DoSOCKSConnectComplete(int result) { |
| if (result == OK) |
| next_state_ = STATE_SSL_CONNECT; |
| |
| return result; |
| } |
| |
| int SSLConnectJob::DoTunnelConnect() { |
| DCHECK(http_proxy_pool_); |
| next_state_ = STATE_TUNNEL_CONNECT_COMPLETE; |
| |
| transport_socket_handle_.reset(new ClientSocketHandle()); |
| scoped_refptr<HttpProxySocketParams> http_proxy_params = |
| params_->GetHttpProxyConnectionParams(); |
| return transport_socket_handle_->Init(group_name(), http_proxy_params, |
| priority(), callback_, http_proxy_pool_, |
| net_log()); |
| } |
| |
| int SSLConnectJob::DoTunnelConnectComplete(int result) { |
| // Extract the information needed to prompt for appropriate proxy |
| // authentication so that when ClientSocketPoolBaseHelper calls |
| // |GetAdditionalErrorState|, we can easily set the state. |
| if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| error_response_info_ = transport_socket_handle_->ssl_error_response_info(); |
| } else if (result == ERR_PROXY_AUTH_REQUESTED || |
| result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { |
| StreamSocket* socket = transport_socket_handle_->socket(); |
| ProxyClientSocket* tunnel_socket = static_cast<ProxyClientSocket*>(socket); |
| error_response_info_ = *tunnel_socket->GetConnectResponseInfo(); |
| } |
| if (result < 0) |
| return result; |
| |
| next_state_ = STATE_SSL_CONNECT; |
| return result; |
| } |
| |
| int SSLConnectJob::DoSSLConnect() { |
| // TODO(pkasting): Remove ScopedTracker below once crbug.com/462815 is fixed. |
| tracked_objects::ScopedTracker tracking_profile( |
| FROM_HERE_WITH_EXPLICIT_FUNCTION("462815 SSLConnectJob::DoSSLConnect")); |
| |
| next_state_ = STATE_SSL_CONNECT_COMPLETE; |
| |
| // Reset the timeout to just the time allowed for the SSL handshake. |
| ResetTimer(base::TimeDelta::FromSeconds(kSSLHandshakeTimeoutInSeconds)); |
| |
| // If the handle has a fresh socket, get its connect start and DNS times. |
| // This should always be the case. |
| const LoadTimingInfo::ConnectTiming& socket_connect_timing = |
| transport_socket_handle_->connect_timing(); |
| if (!transport_socket_handle_->is_reused() && |
| !socket_connect_timing.connect_start.is_null()) { |
| // Overwriting |connect_start| serves two purposes - it adjusts timing so |
| // |connect_start| doesn't include dns times, and it adjusts the time so |
| // as not to include time spent waiting for an idle socket. |
| connect_timing_.connect_start = socket_connect_timing.connect_start; |
| connect_timing_.dns_start = socket_connect_timing.dns_start; |
| connect_timing_.dns_end = socket_connect_timing.dns_end; |
| } |
| |
| connect_timing_.ssl_start = base::TimeTicks::Now(); |
| |
| ssl_socket_ = client_socket_factory_->CreateSSLClientSocket( |
| transport_socket_handle_.Pass(), |
| params_->host_and_port(), |
| params_->ssl_config(), |
| context_); |
| return ssl_socket_->Connect(callback_); |
| } |
| |
| int SSLConnectJob::DoSSLConnectComplete(int result) { |
| // TODO(rvargas): Remove ScopedTracker below once crbug.com/462784 is fixed. |
| tracked_objects::ScopedTracker tracking_profile( |
| FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| "462784 SSLConnectJob::DoSSLConnectComplete")); |
| |
| connect_timing_.ssl_end = base::TimeTicks::Now(); |
| |
| if (result != OK && !server_address_.address().empty()) { |
| connection_attempts_.push_back(ConnectionAttempt(server_address_, result)); |
| server_address_ = IPEndPoint(); |
| } |
| |
| // If we want SPDY over ALPN/NPN, make sure it succeeded. |
| if (params_->expect_spdy() && |
| !NextProtoIsSPDY(ssl_socket_->GetNegotiatedProtocol())) { |
| return ERR_NPN_NEGOTIATION_FAILED; |
| } |
| |
| if (result == OK || |
| ssl_socket_->IgnoreCertError(result, params_->load_flags())) { |
| DCHECK(!connect_timing_.ssl_start.is_null()); |
| base::TimeDelta connect_duration = |
| connect_timing_.ssl_end - connect_timing_.ssl_start; |
| if (params_->expect_spdy()) { |
| UMA_HISTOGRAM_CUSTOM_TIMES("Net.SpdyConnectionLatency_2", |
| connect_duration, |
| base::TimeDelta::FromMilliseconds(1), |
| base::TimeDelta::FromMinutes(1), |
| 100); |
| } |
| |
| UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_2", |
| connect_duration, |
| base::TimeDelta::FromMilliseconds(1), |
| base::TimeDelta::FromMinutes(1), |
| 100); |
| |
| SSLInfo ssl_info; |
| bool has_ssl_info = ssl_socket_->GetSSLInfo(&ssl_info); |
| DCHECK(has_ssl_info); |
| |
| UMA_HISTOGRAM_ENUMERATION("Net.SSLVersion", SSLConnectionStatusToVersion( |
| ssl_info.connection_status), |
| SSL_CONNECTION_VERSION_MAX); |
| |
| uint16 cipher_suite = |
| SSLConnectionStatusToCipherSuite(ssl_info.connection_status); |
| UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_CipherSuite", cipher_suite); |
| |
| const char *str, *cipher_str, *mac_str; |
| bool is_aead; |
| SSLCipherSuiteToStrings(&str, &cipher_str, &mac_str, &is_aead, |
| cipher_suite); |
| // UMA_HISTOGRAM_... macros cache the Histogram instance and thus only work |
| // if the histogram name is constant, so don't generate it dynamically. |
| if (strcmp(str, "RSA") == 0) { |
| UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_KeyExchange.RSA", |
| ssl_info.key_exchange_info); |
| } else if (strncmp(str, "DHE_", 4) == 0) { |
| UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_KeyExchange.DHE", |
| ssl_info.key_exchange_info); |
| } else if (strncmp(str, "ECDHE_", 6) == 0) { |
| UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_KeyExchange.ECDHE", |
| ssl_info.key_exchange_info); |
| } else { |
| NOTREACHED(); |
| } |
| |
| if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME) { |
| UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Resume_Handshake", |
| connect_duration, |
| base::TimeDelta::FromMilliseconds(1), |
| base::TimeDelta::FromMinutes(1), |
| 100); |
| } else if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_FULL) { |
| UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Full_Handshake", |
| connect_duration, |
| base::TimeDelta::FromMilliseconds(1), |
| base::TimeDelta::FromMinutes(1), |
| 100); |
| } |
| |
| const std::string& host = params_->host_and_port().host(); |
| bool is_google = |
| host == "google.com" || |
| (host.size() > 11 && host.rfind(".google.com") == host.size() - 11); |
| if (is_google) { |
| UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google2", |
| connect_duration, |
| base::TimeDelta::FromMilliseconds(1), |
| base::TimeDelta::FromMinutes(1), |
| 100); |
| if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME) { |
| UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google_" |
| "Resume_Handshake", |
| connect_duration, |
| base::TimeDelta::FromMilliseconds(1), |
| base::TimeDelta::FromMinutes(1), |
| 100); |
| } else if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_FULL) { |
| UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google_" |
| "Full_Handshake", |
| connect_duration, |
| base::TimeDelta::FromMilliseconds(1), |
| base::TimeDelta::FromMinutes(1), |
| 100); |
| } |
| } |
| } |
| |
| UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_Connection_Error", std::abs(result)); |
| |
| if (result == OK || IsCertificateError(result)) { |
| SetSocket(ssl_socket_.Pass()); |
| } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| error_response_info_.cert_request_info = new SSLCertRequestInfo; |
| ssl_socket_->GetSSLCertRequestInfo( |
| error_response_info_.cert_request_info.get()); |
| } |
| |
| return result; |
| } |
| |
| SSLConnectJob::State SSLConnectJob::GetInitialState( |
| SSLSocketParams::ConnectionType connection_type) { |
| switch (connection_type) { |
| case SSLSocketParams::DIRECT: |
| return STATE_TRANSPORT_CONNECT; |
| case SSLSocketParams::HTTP_PROXY: |
| return STATE_TUNNEL_CONNECT; |
| case SSLSocketParams::SOCKS_PROXY: |
| return STATE_SOCKS_CONNECT; |
| } |
| NOTREACHED(); |
| return STATE_NONE; |
| } |
| |
| int SSLConnectJob::ConnectInternal() { |
| next_state_ = GetInitialState(params_->GetConnectionType()); |
| return DoLoop(OK); |
| } |
| |
| SSLClientSocketPool::SSLConnectJobFactory::SSLConnectJobFactory( |
| TransportClientSocketPool* transport_pool, |
| SOCKSClientSocketPool* socks_pool, |
| HttpProxyClientSocketPool* http_proxy_pool, |
| ClientSocketFactory* client_socket_factory, |
| const SSLClientSocketContext& context, |
| NetLog* net_log) |
| : transport_pool_(transport_pool), |
| socks_pool_(socks_pool), |
| http_proxy_pool_(http_proxy_pool), |
| client_socket_factory_(client_socket_factory), |
| context_(context), |
| net_log_(net_log) { |
| base::TimeDelta max_transport_timeout = base::TimeDelta(); |
| base::TimeDelta pool_timeout; |
| if (transport_pool_) |
| max_transport_timeout = transport_pool_->ConnectionTimeout(); |
| if (socks_pool_) { |
| pool_timeout = socks_pool_->ConnectionTimeout(); |
| if (pool_timeout > max_transport_timeout) |
| max_transport_timeout = pool_timeout; |
| } |
| if (http_proxy_pool_) { |
| pool_timeout = http_proxy_pool_->ConnectionTimeout(); |
| if (pool_timeout > max_transport_timeout) |
| max_transport_timeout = pool_timeout; |
| } |
| timeout_ = max_transport_timeout + |
| base::TimeDelta::FromSeconds(kSSLHandshakeTimeoutInSeconds); |
| } |
| |
| SSLClientSocketPool::SSLConnectJobFactory::~SSLConnectJobFactory() { |
| } |
| |
| SSLClientSocketPool::SSLClientSocketPool( |
| int max_sockets, |
| int max_sockets_per_group, |
| CertVerifier* cert_verifier, |
| ChannelIDService* channel_id_service, |
| TransportSecurityState* transport_security_state, |
| CTVerifier* cert_transparency_verifier, |
| CertPolicyEnforcer* cert_policy_enforcer, |
| const std::string& ssl_session_cache_shard, |
| ClientSocketFactory* client_socket_factory, |
| TransportClientSocketPool* transport_pool, |
| SOCKSClientSocketPool* socks_pool, |
| HttpProxyClientSocketPool* http_proxy_pool, |
| SSLConfigService* ssl_config_service, |
| NetLog* net_log) |
| : transport_pool_(transport_pool), |
| socks_pool_(socks_pool), |
| http_proxy_pool_(http_proxy_pool), |
| base_(this, |
| max_sockets, |
| max_sockets_per_group, |
| ClientSocketPool::unused_idle_socket_timeout(), |
| ClientSocketPool::used_idle_socket_timeout(), |
| new SSLConnectJobFactory( |
| transport_pool, |
| socks_pool, |
| http_proxy_pool, |
| client_socket_factory, |
| SSLClientSocketContext(cert_verifier, |
| channel_id_service, |
| transport_security_state, |
| cert_transparency_verifier, |
| cert_policy_enforcer, |
| ssl_session_cache_shard), |
| net_log)), |
| ssl_config_service_(ssl_config_service) { |
| if (ssl_config_service_.get()) |
| ssl_config_service_->AddObserver(this); |
| if (transport_pool_) |
| base_.AddLowerLayeredPool(transport_pool_); |
| if (socks_pool_) |
| base_.AddLowerLayeredPool(socks_pool_); |
| if (http_proxy_pool_) |
| base_.AddLowerLayeredPool(http_proxy_pool_); |
| } |
| |
| SSLClientSocketPool::~SSLClientSocketPool() { |
| if (ssl_config_service_.get()) |
| ssl_config_service_->RemoveObserver(this); |
| } |
| |
| scoped_ptr<ConnectJob> SSLClientSocketPool::SSLConnectJobFactory::NewConnectJob( |
| const std::string& group_name, |
| const PoolBase::Request& request, |
| ConnectJob::Delegate* delegate) const { |
| return scoped_ptr<ConnectJob>(new SSLConnectJob(group_name, |
| request.priority(), |
| request.params(), |
| ConnectionTimeout(), |
| transport_pool_, |
| socks_pool_, |
| http_proxy_pool_, |
| client_socket_factory_, |
| context_, |
| delegate, |
| net_log_)); |
| } |
| |
| base::TimeDelta SSLClientSocketPool::SSLConnectJobFactory::ConnectionTimeout() |
| const { |
| return timeout_; |
| } |
| |
| int SSLClientSocketPool::RequestSocket(const std::string& group_name, |
| const void* socket_params, |
| RequestPriority priority, |
| ClientSocketHandle* handle, |
| const CompletionCallback& callback, |
| const BoundNetLog& net_log) { |
| const scoped_refptr<SSLSocketParams>* casted_socket_params = |
| static_cast<const scoped_refptr<SSLSocketParams>*>(socket_params); |
| |
| return base_.RequestSocket(group_name, *casted_socket_params, priority, |
| handle, callback, net_log); |
| } |
| |
| void SSLClientSocketPool::RequestSockets( |
| const std::string& group_name, |
| const void* params, |
| int num_sockets, |
| const BoundNetLog& net_log) { |
| const scoped_refptr<SSLSocketParams>* casted_params = |
| static_cast<const scoped_refptr<SSLSocketParams>*>(params); |
| |
| base_.RequestSockets(group_name, *casted_params, num_sockets, net_log); |
| } |
| |
| void SSLClientSocketPool::CancelRequest(const std::string& group_name, |
| ClientSocketHandle* handle) { |
| base_.CancelRequest(group_name, handle); |
| } |
| |
| void SSLClientSocketPool::ReleaseSocket(const std::string& group_name, |
| scoped_ptr<StreamSocket> socket, |
| int id) { |
| base_.ReleaseSocket(group_name, socket.Pass(), id); |
| } |
| |
| void SSLClientSocketPool::FlushWithError(int error) { |
| base_.FlushWithError(error); |
| } |
| |
| void SSLClientSocketPool::CloseIdleSockets() { |
| base_.CloseIdleSockets(); |
| } |
| |
| int SSLClientSocketPool::IdleSocketCount() const { |
| return base_.idle_socket_count(); |
| } |
| |
| int SSLClientSocketPool::IdleSocketCountInGroup( |
| const std::string& group_name) const { |
| return base_.IdleSocketCountInGroup(group_name); |
| } |
| |
| LoadState SSLClientSocketPool::GetLoadState( |
| const std::string& group_name, const ClientSocketHandle* handle) const { |
| return base_.GetLoadState(group_name, handle); |
| } |
| |
| scoped_ptr<base::DictionaryValue> SSLClientSocketPool::GetInfoAsValue( |
| const std::string& name, |
| const std::string& type, |
| bool include_nested_pools) const { |
| scoped_ptr<base::DictionaryValue> dict(base_.GetInfoAsValue(name, type)); |
| if (include_nested_pools) { |
| base::ListValue* list = new base::ListValue(); |
| if (transport_pool_) { |
| list->Append(transport_pool_->GetInfoAsValue("transport_socket_pool", |
| "transport_socket_pool", |
| false)); |
| } |
| if (socks_pool_) { |
| list->Append(socks_pool_->GetInfoAsValue("socks_pool", |
| "socks_pool", |
| true)); |
| } |
| if (http_proxy_pool_) { |
| list->Append(http_proxy_pool_->GetInfoAsValue("http_proxy_pool", |
| "http_proxy_pool", |
| true)); |
| } |
| dict->Set("nested_pools", list); |
| } |
| return dict.Pass(); |
| } |
| |
| base::TimeDelta SSLClientSocketPool::ConnectionTimeout() const { |
| return base_.ConnectionTimeout(); |
| } |
| |
| bool SSLClientSocketPool::IsStalled() const { |
| return base_.IsStalled(); |
| } |
| |
| void SSLClientSocketPool::AddHigherLayeredPool(HigherLayeredPool* higher_pool) { |
| base_.AddHigherLayeredPool(higher_pool); |
| } |
| |
| void SSLClientSocketPool::RemoveHigherLayeredPool( |
| HigherLayeredPool* higher_pool) { |
| base_.RemoveHigherLayeredPool(higher_pool); |
| } |
| |
| bool SSLClientSocketPool::CloseOneIdleConnection() { |
| if (base_.CloseOneIdleSocket()) |
| return true; |
| return base_.CloseOneIdleConnectionInHigherLayeredPool(); |
| } |
| |
| void SSLClientSocketPool::OnSSLConfigChanged() { |
| FlushWithError(ERR_NETWORK_CHANGED); |
| } |
| |
| } // namespace net |