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