Add signalSyncPoint to the WebGraphicsContext3D command buffer impls.
[chromium-blink-merge.git] / net / socket / ssl_client_socket_pool.cc
blob0f3da13071e00164b071102922575c34ab96bf37
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/socket/ssl_client_socket_pool.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/metrics/field_trial.h"
10 #include "base/metrics/histogram.h"
11 #include "base/values.h"
12 #include "net/base/host_port_pair.h"
13 #include "net/base/net_errors.h"
14 #include "net/http/http_proxy_client_socket.h"
15 #include "net/http/http_proxy_client_socket_pool.h"
16 #include "net/socket/client_socket_factory.h"
17 #include "net/socket/client_socket_handle.h"
18 #include "net/socket/socks_client_socket_pool.h"
19 #include "net/socket/ssl_client_socket.h"
20 #include "net/socket/transport_client_socket_pool.h"
21 #include "net/ssl/ssl_cert_request_info.h"
23 namespace net {
25 SSLSocketParams::SSLSocketParams(
26 const scoped_refptr<TransportSocketParams>& transport_params,
27 const scoped_refptr<SOCKSSocketParams>& socks_params,
28 const scoped_refptr<HttpProxySocketParams>& http_proxy_params,
29 ProxyServer::Scheme proxy,
30 const HostPortPair& host_and_port,
31 const SSLConfig& ssl_config,
32 int load_flags,
33 bool force_spdy_over_ssl,
34 bool want_spdy_over_npn)
35 : transport_params_(transport_params),
36 http_proxy_params_(http_proxy_params),
37 socks_params_(socks_params),
38 proxy_(proxy),
39 host_and_port_(host_and_port),
40 ssl_config_(ssl_config),
41 load_flags_(load_flags),
42 force_spdy_over_ssl_(force_spdy_over_ssl),
43 want_spdy_over_npn_(want_spdy_over_npn),
44 ignore_limits_(false) {
45 switch (proxy_) {
46 case ProxyServer::SCHEME_DIRECT:
47 DCHECK(transport_params_.get() != NULL);
48 DCHECK(http_proxy_params_.get() == NULL);
49 DCHECK(socks_params_.get() == NULL);
50 ignore_limits_ = transport_params_->ignore_limits();
51 break;
52 case ProxyServer::SCHEME_HTTP:
53 case ProxyServer::SCHEME_HTTPS:
54 DCHECK(transport_params_.get() == NULL);
55 DCHECK(http_proxy_params_.get() != NULL);
56 DCHECK(socks_params_.get() == NULL);
57 ignore_limits_ = http_proxy_params_->ignore_limits();
58 break;
59 case ProxyServer::SCHEME_SOCKS4:
60 case ProxyServer::SCHEME_SOCKS5:
61 DCHECK(transport_params_.get() == NULL);
62 DCHECK(http_proxy_params_.get() == NULL);
63 DCHECK(socks_params_.get() != NULL);
64 ignore_limits_ = socks_params_->ignore_limits();
65 break;
66 default:
67 LOG(DFATAL) << "unknown proxy type";
68 break;
72 SSLSocketParams::~SSLSocketParams() {}
74 // Timeout for the SSL handshake portion of the connect.
75 static const int kSSLHandshakeTimeoutInSeconds = 30;
77 SSLConnectJob::SSLConnectJob(const std::string& group_name,
78 const scoped_refptr<SSLSocketParams>& params,
79 const base::TimeDelta& timeout_duration,
80 TransportClientSocketPool* transport_pool,
81 SOCKSClientSocketPool* socks_pool,
82 HttpProxyClientSocketPool* http_proxy_pool,
83 ClientSocketFactory* client_socket_factory,
84 HostResolver* host_resolver,
85 const SSLClientSocketContext& context,
86 Delegate* delegate,
87 NetLog* net_log)
88 : ConnectJob(group_name, timeout_duration, delegate,
89 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
90 params_(params),
91 transport_pool_(transport_pool),
92 socks_pool_(socks_pool),
93 http_proxy_pool_(http_proxy_pool),
94 client_socket_factory_(client_socket_factory),
95 host_resolver_(host_resolver),
96 context_(context),
97 ALLOW_THIS_IN_INITIALIZER_LIST(
98 callback_(base::Bind(&SSLConnectJob::OnIOComplete,
99 base::Unretained(this)))) {}
101 SSLConnectJob::~SSLConnectJob() {}
103 LoadState SSLConnectJob::GetLoadState() const {
104 switch (next_state_) {
105 case STATE_TUNNEL_CONNECT_COMPLETE:
106 if (transport_socket_handle_->socket())
107 return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL;
108 // else, fall through.
109 case STATE_TRANSPORT_CONNECT:
110 case STATE_TRANSPORT_CONNECT_COMPLETE:
111 case STATE_SOCKS_CONNECT:
112 case STATE_SOCKS_CONNECT_COMPLETE:
113 case STATE_TUNNEL_CONNECT:
114 return transport_socket_handle_->GetLoadState();
115 case STATE_SSL_CONNECT:
116 case STATE_SSL_CONNECT_COMPLETE:
117 return LOAD_STATE_SSL_HANDSHAKE;
118 default:
119 NOTREACHED();
120 return LOAD_STATE_IDLE;
124 void SSLConnectJob::GetAdditionalErrorState(ClientSocketHandle* handle) {
125 // Headers in |error_response_info_| indicate a proxy tunnel setup
126 // problem. See DoTunnelConnectComplete.
127 if (error_response_info_.headers) {
128 handle->set_pending_http_proxy_connection(
129 transport_socket_handle_.release());
131 handle->set_ssl_error_response_info(error_response_info_);
132 if (!connect_timing_.ssl_start.is_null())
133 handle->set_is_ssl_error(true);
136 void SSLConnectJob::OnIOComplete(int result) {
137 int rv = DoLoop(result);
138 if (rv != ERR_IO_PENDING)
139 NotifyDelegateOfCompletion(rv); // Deletes |this|.
142 int SSLConnectJob::DoLoop(int result) {
143 DCHECK_NE(next_state_, STATE_NONE);
145 int rv = result;
146 do {
147 State state = next_state_;
148 next_state_ = STATE_NONE;
149 switch (state) {
150 case STATE_TRANSPORT_CONNECT:
151 DCHECK_EQ(OK, rv);
152 rv = DoTransportConnect();
153 break;
154 case STATE_TRANSPORT_CONNECT_COMPLETE:
155 rv = DoTransportConnectComplete(rv);
156 break;
157 case STATE_SOCKS_CONNECT:
158 DCHECK_EQ(OK, rv);
159 rv = DoSOCKSConnect();
160 break;
161 case STATE_SOCKS_CONNECT_COMPLETE:
162 rv = DoSOCKSConnectComplete(rv);
163 break;
164 case STATE_TUNNEL_CONNECT:
165 DCHECK_EQ(OK, rv);
166 rv = DoTunnelConnect();
167 break;
168 case STATE_TUNNEL_CONNECT_COMPLETE:
169 rv = DoTunnelConnectComplete(rv);
170 break;
171 case STATE_SSL_CONNECT:
172 DCHECK_EQ(OK, rv);
173 rv = DoSSLConnect();
174 break;
175 case STATE_SSL_CONNECT_COMPLETE:
176 rv = DoSSLConnectComplete(rv);
177 break;
178 default:
179 NOTREACHED() << "bad state";
180 rv = ERR_FAILED;
181 break;
183 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
185 return rv;
188 int SSLConnectJob::DoTransportConnect() {
189 DCHECK(transport_pool_);
191 next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE;
192 transport_socket_handle_.reset(new ClientSocketHandle());
193 scoped_refptr<TransportSocketParams> transport_params =
194 params_->transport_params();
195 return transport_socket_handle_->Init(
196 group_name(), transport_params,
197 transport_params->destination().priority(), callback_, transport_pool_,
198 net_log());
201 int SSLConnectJob::DoTransportConnectComplete(int result) {
202 if (result == OK)
203 next_state_ = STATE_SSL_CONNECT;
205 return result;
208 int SSLConnectJob::DoSOCKSConnect() {
209 DCHECK(socks_pool_);
210 next_state_ = STATE_SOCKS_CONNECT_COMPLETE;
211 transport_socket_handle_.reset(new ClientSocketHandle());
212 scoped_refptr<SOCKSSocketParams> socks_params = params_->socks_params();
213 return transport_socket_handle_->Init(
214 group_name(), socks_params, socks_params->destination().priority(),
215 callback_, socks_pool_, net_log());
218 int SSLConnectJob::DoSOCKSConnectComplete(int result) {
219 if (result == OK)
220 next_state_ = STATE_SSL_CONNECT;
222 return result;
225 int SSLConnectJob::DoTunnelConnect() {
226 DCHECK(http_proxy_pool_);
227 next_state_ = STATE_TUNNEL_CONNECT_COMPLETE;
229 transport_socket_handle_.reset(new ClientSocketHandle());
230 scoped_refptr<HttpProxySocketParams> http_proxy_params =
231 params_->http_proxy_params();
232 return transport_socket_handle_->Init(
233 group_name(), http_proxy_params,
234 http_proxy_params->destination().priority(), callback_, http_proxy_pool_,
235 net_log());
238 int SSLConnectJob::DoTunnelConnectComplete(int result) {
239 // Extract the information needed to prompt for appropriate proxy
240 // authentication so that when ClientSocketPoolBaseHelper calls
241 // |GetAdditionalErrorState|, we can easily set the state.
242 if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
243 error_response_info_ = transport_socket_handle_->ssl_error_response_info();
244 } else if (result == ERR_PROXY_AUTH_REQUESTED ||
245 result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) {
246 StreamSocket* socket = transport_socket_handle_->socket();
247 HttpProxyClientSocket* tunnel_socket =
248 static_cast<HttpProxyClientSocket*>(socket);
249 error_response_info_ = *tunnel_socket->GetConnectResponseInfo();
251 if (result < 0)
252 return result;
254 next_state_ = STATE_SSL_CONNECT;
255 return result;
258 int SSLConnectJob::DoSSLConnect() {
259 next_state_ = STATE_SSL_CONNECT_COMPLETE;
260 // Reset the timeout to just the time allowed for the SSL handshake.
261 ResetTimer(base::TimeDelta::FromSeconds(kSSLHandshakeTimeoutInSeconds));
263 // If the handle has a fresh socket, get its connect start and DNS times.
264 // This should always be the case.
265 const LoadTimingInfo::ConnectTiming& socket_connect_timing =
266 transport_socket_handle_->connect_timing();
267 if (!transport_socket_handle_->is_reused() &&
268 !socket_connect_timing.connect_start.is_null()) {
269 // Overwriting |connect_start| serves two purposes - it adjusts timing so
270 // |connect_start| doesn't include dns times, and it adjusts the time so
271 // as not to include time spent waiting for an idle socket.
272 connect_timing_.connect_start = socket_connect_timing.connect_start;
273 connect_timing_.dns_start = socket_connect_timing.dns_start;
274 connect_timing_.dns_end = socket_connect_timing.dns_end;
277 connect_timing_.ssl_start = base::TimeTicks::Now();
279 ssl_socket_.reset(client_socket_factory_->CreateSSLClientSocket(
280 transport_socket_handle_.release(), params_->host_and_port(),
281 params_->ssl_config(), context_));
282 return ssl_socket_->Connect(callback_);
285 int SSLConnectJob::DoSSLConnectComplete(int result) {
286 connect_timing_.ssl_end = base::TimeTicks::Now();
288 SSLClientSocket::NextProtoStatus status =
289 SSLClientSocket::kNextProtoUnsupported;
290 std::string proto;
291 std::string server_protos;
292 // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket
293 // that hasn't had SSL_ImportFD called on it. If we get a certificate error
294 // here, then we know that we called SSL_ImportFD.
295 if (result == OK || IsCertificateError(result))
296 status = ssl_socket_->GetNextProto(&proto, &server_protos);
298 // If we want spdy over npn, make sure it succeeded.
299 if (status == SSLClientSocket::kNextProtoNegotiated) {
300 ssl_socket_->set_was_npn_negotiated(true);
301 NextProto protocol_negotiated =
302 SSLClientSocket::NextProtoFromString(proto);
303 ssl_socket_->set_protocol_negotiated(protocol_negotiated);
304 // If we negotiated a SPDY version, it must have been present in
305 // SSLConfig::next_protos.
306 // TODO(mbelshe): Verify this.
307 if (protocol_negotiated >= kProtoSPDYMinimumVersion &&
308 protocol_negotiated <= kProtoSPDYMaximumVersion) {
309 ssl_socket_->set_was_spdy_negotiated(true);
312 if (params_->want_spdy_over_npn() && !ssl_socket_->was_spdy_negotiated())
313 return ERR_NPN_NEGOTIATION_FAILED;
315 // Spdy might be turned on by default, or it might be over npn.
316 bool using_spdy = params_->force_spdy_over_ssl() ||
317 params_->want_spdy_over_npn();
319 if (result == OK ||
320 ssl_socket_->IgnoreCertError(result, params_->load_flags())) {
321 DCHECK(!connect_timing_.ssl_start.is_null());
322 base::TimeDelta connect_duration =
323 connect_timing_.ssl_end - connect_timing_.ssl_start;
324 if (using_spdy) {
325 UMA_HISTOGRAM_CUSTOM_TIMES("Net.SpdyConnectionLatency_2",
326 connect_duration,
327 base::TimeDelta::FromMilliseconds(1),
328 base::TimeDelta::FromMinutes(1),
329 100);
332 UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_2",
333 connect_duration,
334 base::TimeDelta::FromMilliseconds(1),
335 base::TimeDelta::FromMinutes(1),
336 100);
338 SSLInfo ssl_info;
339 ssl_socket_->GetSSLInfo(&ssl_info);
341 if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME) {
342 UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Resume_Handshake",
343 connect_duration,
344 base::TimeDelta::FromMilliseconds(1),
345 base::TimeDelta::FromMinutes(1),
346 100);
347 } else if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_FULL) {
348 UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Full_Handshake",
349 connect_duration,
350 base::TimeDelta::FromMilliseconds(1),
351 base::TimeDelta::FromMinutes(1),
352 100);
355 const std::string& host = params_->host_and_port().host();
356 bool is_google = host == "google.com" ||
357 (host.size() > 11 &&
358 host.rfind(".google.com") == host.size() - 11);
359 if (is_google) {
360 UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google2",
361 connect_duration,
362 base::TimeDelta::FromMilliseconds(1),
363 base::TimeDelta::FromMinutes(1),
364 100);
365 if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME) {
366 UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google_"
367 "Resume_Handshake",
368 connect_duration,
369 base::TimeDelta::FromMilliseconds(1),
370 base::TimeDelta::FromMinutes(1),
371 100);
372 } else if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_FULL) {
373 UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google_"
374 "Full_Handshake",
375 connect_duration,
376 base::TimeDelta::FromMilliseconds(1),
377 base::TimeDelta::FromMinutes(1),
378 100);
383 if (result == OK || IsCertificateError(result)) {
384 set_socket(ssl_socket_.release());
385 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
386 error_response_info_.cert_request_info = new SSLCertRequestInfo;
387 ssl_socket_->GetSSLCertRequestInfo(error_response_info_.cert_request_info);
390 return result;
393 int SSLConnectJob::ConnectInternal() {
394 switch (params_->proxy()) {
395 case ProxyServer::SCHEME_DIRECT:
396 next_state_ = STATE_TRANSPORT_CONNECT;
397 break;
398 case ProxyServer::SCHEME_HTTP:
399 case ProxyServer::SCHEME_HTTPS:
400 next_state_ = STATE_TUNNEL_CONNECT;
401 break;
402 case ProxyServer::SCHEME_SOCKS4:
403 case ProxyServer::SCHEME_SOCKS5:
404 next_state_ = STATE_SOCKS_CONNECT;
405 break;
406 default:
407 NOTREACHED() << "unknown proxy type";
408 break;
410 return DoLoop(OK);
413 SSLClientSocketPool::SSLConnectJobFactory::SSLConnectJobFactory(
414 TransportClientSocketPool* transport_pool,
415 SOCKSClientSocketPool* socks_pool,
416 HttpProxyClientSocketPool* http_proxy_pool,
417 ClientSocketFactory* client_socket_factory,
418 HostResolver* host_resolver,
419 const SSLClientSocketContext& context,
420 NetLog* net_log)
421 : transport_pool_(transport_pool),
422 socks_pool_(socks_pool),
423 http_proxy_pool_(http_proxy_pool),
424 client_socket_factory_(client_socket_factory),
425 host_resolver_(host_resolver),
426 context_(context),
427 net_log_(net_log) {
428 base::TimeDelta max_transport_timeout = base::TimeDelta();
429 base::TimeDelta pool_timeout;
430 if (transport_pool_)
431 max_transport_timeout = transport_pool_->ConnectionTimeout();
432 if (socks_pool_) {
433 pool_timeout = socks_pool_->ConnectionTimeout();
434 if (pool_timeout > max_transport_timeout)
435 max_transport_timeout = pool_timeout;
437 if (http_proxy_pool_) {
438 pool_timeout = http_proxy_pool_->ConnectionTimeout();
439 if (pool_timeout > max_transport_timeout)
440 max_transport_timeout = pool_timeout;
442 timeout_ = max_transport_timeout +
443 base::TimeDelta::FromSeconds(kSSLHandshakeTimeoutInSeconds);
446 SSLClientSocketPool::SSLClientSocketPool(
447 int max_sockets,
448 int max_sockets_per_group,
449 ClientSocketPoolHistograms* histograms,
450 HostResolver* host_resolver,
451 CertVerifier* cert_verifier,
452 ServerBoundCertService* server_bound_cert_service,
453 TransportSecurityState* transport_security_state,
454 const std::string& ssl_session_cache_shard,
455 ClientSocketFactory* client_socket_factory,
456 TransportClientSocketPool* transport_pool,
457 SOCKSClientSocketPool* socks_pool,
458 HttpProxyClientSocketPool* http_proxy_pool,
459 SSLConfigService* ssl_config_service,
460 NetLog* net_log)
461 : transport_pool_(transport_pool),
462 socks_pool_(socks_pool),
463 http_proxy_pool_(http_proxy_pool),
464 base_(max_sockets, max_sockets_per_group, histograms,
465 ClientSocketPool::unused_idle_socket_timeout(),
466 ClientSocketPool::used_idle_socket_timeout(),
467 new SSLConnectJobFactory(transport_pool,
468 socks_pool,
469 http_proxy_pool,
470 client_socket_factory,
471 host_resolver,
472 SSLClientSocketContext(
473 cert_verifier,
474 server_bound_cert_service,
475 transport_security_state,
476 ssl_session_cache_shard),
477 net_log)),
478 ssl_config_service_(ssl_config_service) {
479 if (ssl_config_service_)
480 ssl_config_service_->AddObserver(this);
481 if (transport_pool_)
482 transport_pool_->AddLayeredPool(this);
483 if (socks_pool_)
484 socks_pool_->AddLayeredPool(this);
485 if (http_proxy_pool_)
486 http_proxy_pool_->AddLayeredPool(this);
489 SSLClientSocketPool::~SSLClientSocketPool() {
490 if (http_proxy_pool_)
491 http_proxy_pool_->RemoveLayeredPool(this);
492 if (socks_pool_)
493 socks_pool_->RemoveLayeredPool(this);
494 if (transport_pool_)
495 transport_pool_->RemoveLayeredPool(this);
496 if (ssl_config_service_)
497 ssl_config_service_->RemoveObserver(this);
500 ConnectJob* SSLClientSocketPool::SSLConnectJobFactory::NewConnectJob(
501 const std::string& group_name,
502 const PoolBase::Request& request,
503 ConnectJob::Delegate* delegate) const {
504 return new SSLConnectJob(group_name, request.params(), ConnectionTimeout(),
505 transport_pool_, socks_pool_, http_proxy_pool_,
506 client_socket_factory_, host_resolver_,
507 context_, delegate, net_log_);
510 base::TimeDelta
511 SSLClientSocketPool::SSLConnectJobFactory::ConnectionTimeout() const {
512 return timeout_;
515 int SSLClientSocketPool::RequestSocket(const std::string& group_name,
516 const void* socket_params,
517 RequestPriority priority,
518 ClientSocketHandle* handle,
519 const CompletionCallback& callback,
520 const BoundNetLog& net_log) {
521 const scoped_refptr<SSLSocketParams>* casted_socket_params =
522 static_cast<const scoped_refptr<SSLSocketParams>*>(socket_params);
524 return base_.RequestSocket(group_name, *casted_socket_params, priority,
525 handle, callback, net_log);
528 void SSLClientSocketPool::RequestSockets(
529 const std::string& group_name,
530 const void* params,
531 int num_sockets,
532 const BoundNetLog& net_log) {
533 const scoped_refptr<SSLSocketParams>* casted_params =
534 static_cast<const scoped_refptr<SSLSocketParams>*>(params);
536 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
539 void SSLClientSocketPool::CancelRequest(const std::string& group_name,
540 ClientSocketHandle* handle) {
541 base_.CancelRequest(group_name, handle);
544 void SSLClientSocketPool::ReleaseSocket(const std::string& group_name,
545 StreamSocket* socket, int id) {
546 base_.ReleaseSocket(group_name, socket, id);
549 void SSLClientSocketPool::FlushWithError(int error) {
550 base_.FlushWithError(error);
553 bool SSLClientSocketPool::IsStalled() const {
554 return base_.IsStalled() ||
555 (transport_pool_ && transport_pool_->IsStalled()) ||
556 (socks_pool_ && socks_pool_->IsStalled()) ||
557 (http_proxy_pool_ && http_proxy_pool_->IsStalled());
560 void SSLClientSocketPool::CloseIdleSockets() {
561 base_.CloseIdleSockets();
564 int SSLClientSocketPool::IdleSocketCount() const {
565 return base_.idle_socket_count();
568 int SSLClientSocketPool::IdleSocketCountInGroup(
569 const std::string& group_name) const {
570 return base_.IdleSocketCountInGroup(group_name);
573 LoadState SSLClientSocketPool::GetLoadState(
574 const std::string& group_name, const ClientSocketHandle* handle) const {
575 return base_.GetLoadState(group_name, handle);
578 void SSLClientSocketPool::AddLayeredPool(LayeredPool* layered_pool) {
579 base_.AddLayeredPool(layered_pool);
582 void SSLClientSocketPool::RemoveLayeredPool(LayeredPool* layered_pool) {
583 base_.RemoveLayeredPool(layered_pool);
586 DictionaryValue* SSLClientSocketPool::GetInfoAsValue(
587 const std::string& name,
588 const std::string& type,
589 bool include_nested_pools) const {
590 DictionaryValue* dict = base_.GetInfoAsValue(name, type);
591 if (include_nested_pools) {
592 ListValue* list = new ListValue();
593 if (transport_pool_) {
594 list->Append(transport_pool_->GetInfoAsValue("transport_socket_pool",
595 "transport_socket_pool",
596 false));
598 if (socks_pool_) {
599 list->Append(socks_pool_->GetInfoAsValue("socks_pool",
600 "socks_pool",
601 true));
603 if (http_proxy_pool_) {
604 list->Append(http_proxy_pool_->GetInfoAsValue("http_proxy_pool",
605 "http_proxy_pool",
606 true));
608 dict->Set("nested_pools", list);
610 return dict;
613 base::TimeDelta SSLClientSocketPool::ConnectionTimeout() const {
614 return base_.ConnectionTimeout();
617 ClientSocketPoolHistograms* SSLClientSocketPool::histograms() const {
618 return base_.histograms();
621 void SSLClientSocketPool::OnSSLConfigChanged() {
622 FlushWithError(ERR_NETWORK_CHANGED);
625 bool SSLClientSocketPool::CloseOneIdleConnection() {
626 if (base_.CloseOneIdleSocket())
627 return true;
628 return base_.CloseOneIdleConnectionInLayeredPool();
631 } // namespace net