Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: net/socket/ssl_client_socket_pool.cc

Issue 384873002: This CL changes the lifespan of SSLConnectJobMessengers so that they are created only when needed, (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@useloop
Patch Set: Removed FormatSessionCacheKey function. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/socket/ssl_client_socket_pool.h" 5 #include "net/socket/ssl_client_socket_pool.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/metrics/field_trial.h" 9 #include "base/metrics/field_trial.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 const scoped_refptr<HttpProxySocketParams>& 92 const scoped_refptr<HttpProxySocketParams>&
93 SSLSocketParams::GetHttpProxyConnectionParams() const { 93 SSLSocketParams::GetHttpProxyConnectionParams() const {
94 DCHECK_EQ(GetConnectionType(), HTTP_PROXY); 94 DCHECK_EQ(GetConnectionType(), HTTP_PROXY);
95 return http_proxy_params_; 95 return http_proxy_params_;
96 } 96 }
97 97
98 SSLConnectJobMessenger::SSLConnectJobMessenger() : weak_factory_(this) { 98 SSLConnectJobMessenger::SSLConnectJobMessenger() : weak_factory_(this) {
99 } 99 }
100 100
101 bool SSLConnectJobMessenger::CanProceed(SSLClientSocket* ssl_socket) { 101 bool SSLConnectJobMessenger::CanProceed(SSLClientSocket* ssl_socket) {
102 // If the session is in the session cache, or there are no connecting 102 // If there are no connecting sockets allow the connection to proceed.
103 // sockets allow the connection to proceed. 103 return connecting_sockets_.empty();
104 if (ssl_socket->InSessionCache() || connecting_sockets_.empty()) {
105 return true;
106 }
107 return false;
108 } 104 }
109 105
110 void SSLConnectJobMessenger::MonitorConnectionResult( 106 void SSLConnectJobMessenger::MonitorConnectionResult(
111 SSLClientSocket* ssl_socket) { 107 SSLClientSocket* ssl_socket) {
112 connecting_sockets_.push_back(ssl_socket); 108 connecting_sockets_.push_back(ssl_socket);
113 ssl_socket->SetIsLeader(); 109 ssl_socket->SetIsLeader();
114 // SSLConnectJobMessenger weak_ptrs are used here to ensure that 110 // SSLConnectJobMessenger weak_ptrs are used here to ensure that
115 // tasks posted with these callbacks are deregistered if the 111 // tasks posted with these callbacks are deregistered if the
116 // SSLConnectJobMessenger should become invalid before they're run. 112 // SSLConnectJobMessenger should become invalid before they're run.
117 ssl_socket->SetSocketFailureCallback(base::Bind( 113 ssl_socket->SetSocketFailureCallback(base::Bind(
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 // Erase all deleted sockets and their callbacks, as well as the socket that 158 // Erase all deleted sockets and their callbacks, as well as the socket that
163 // will 159 // will
164 // be connected next. 160 // be connected next.
165 pending_sockets_and_callbacks_.erase(pending_sockets_and_callbacks_.begin(), 161 pending_sockets_and_callbacks_.erase(pending_sockets_and_callbacks_.begin(),
166 ++it); 162 ++it);
167 163
168 MonitorConnectionResult(ssl_socket); 164 MonitorConnectionResult(ssl_socket);
169 callback.Run(); 165 callback.Run();
170 } 166 }
171 167
168 bool SSLConnectJobMessenger::IsNeeded() {
169 return pending_sockets_and_callbacks_.empty() && connecting_sockets_.empty();
170 }
171
172 void SSLConnectJobMessenger::RunAllJobs( 172 void SSLConnectJobMessenger::RunAllJobs(
173 std::vector<SocketAndCallback>& pending_sockets_and_callbacks) { 173 std::vector<SocketAndCallback>& pending_sockets_and_callbacks) {
174 scoped_refptr<base::SingleThreadTaskRunner> task_runner = 174 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
175 base::ThreadTaskRunnerHandle::Get(); 175 base::ThreadTaskRunnerHandle::Get();
176 for (std::vector<SocketAndCallback>::const_iterator it = 176 for (std::vector<SocketAndCallback>::const_iterator it =
177 pending_sockets_and_callbacks.begin(); 177 pending_sockets_and_callbacks.begin();
178 it != pending_sockets_and_callbacks.end(); 178 it != pending_sockets_and_callbacks.end();
179 ++it) 179 ++it)
180 task_runner->PostTask(FROM_HERE, it->callback); 180 task_runner->PostTask(FROM_HERE, it->callback);
181 } 181 }
182 182
183 // Timeout for the SSL handshake portion of the connect. 183 // Timeout for the SSL handshake portion of the connect.
184 static const int kSSLHandshakeTimeoutInSeconds = 30; 184 static const int kSSLHandshakeTimeoutInSeconds = 30;
185 185
186 SSLConnectJob::SSLConnectJob(const std::string& group_name, 186 SSLConnectJob::SSLConnectJob(const std::string& group_name,
187 RequestPriority priority, 187 RequestPriority priority,
188 const scoped_refptr<SSLSocketParams>& params, 188 const scoped_refptr<SSLSocketParams>& params,
189 const base::TimeDelta& timeout_duration, 189 const base::TimeDelta& timeout_duration,
190 TransportClientSocketPool* transport_pool, 190 TransportClientSocketPool* transport_pool,
191 SOCKSClientSocketPool* socks_pool, 191 SOCKSClientSocketPool* socks_pool,
192 HttpProxyClientSocketPool* http_proxy_pool, 192 HttpProxyClientSocketPool* http_proxy_pool,
193 ClientSocketFactory* client_socket_factory, 193 ClientSocketFactory* client_socket_factory,
194 HostResolver* host_resolver, 194 HostResolver* host_resolver,
195 const SSLClientSocketContext& context, 195 const SSLClientSocketContext& context,
196 SSLConnectJobMessenger* messenger, 196 SSLConnectJobMessenger* messenger,
197 AddMessengerCallback add_messenger_callback,
198 DeleteMessengerCallback delete_messenger_callback,
197 Delegate* delegate, 199 Delegate* delegate,
198 NetLog* net_log) 200 NetLog* net_log)
199 : ConnectJob(group_name, 201 : ConnectJob(group_name,
200 timeout_duration, 202 timeout_duration,
201 priority, 203 priority,
202 delegate, 204 delegate,
203 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)), 205 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
204 params_(params), 206 params_(params),
205 transport_pool_(transport_pool), 207 transport_pool_(transport_pool),
206 socks_pool_(socks_pool), 208 socks_pool_(socks_pool),
207 http_proxy_pool_(http_proxy_pool), 209 http_proxy_pool_(http_proxy_pool),
208 client_socket_factory_(client_socket_factory), 210 client_socket_factory_(client_socket_factory),
209 host_resolver_(host_resolver), 211 host_resolver_(host_resolver),
210 context_(context.cert_verifier, 212 context_(context.cert_verifier,
211 context.server_bound_cert_service, 213 context.server_bound_cert_service,
212 context.transport_security_state, 214 context.transport_security_state,
213 context.cert_transparency_verifier, 215 context.cert_transparency_verifier,
214 (params->privacy_mode() == PRIVACY_MODE_ENABLED 216 (params->privacy_mode() == PRIVACY_MODE_ENABLED
215 ? "pm/" + context.ssl_session_cache_shard 217 ? "pm/" + context.ssl_session_cache_shard
216 : context.ssl_session_cache_shard)), 218 : context.ssl_session_cache_shard)),
217 io_callback_( 219 io_callback_(
218 base::Bind(&SSLConnectJob::OnIOComplete, base::Unretained(this))), 220 base::Bind(&SSLConnectJob::OnIOComplete, base::Unretained(this))),
219 messenger_(messenger), 221 messenger_(messenger),
220 weak_factory_(this) { 222 weak_factory_(this),
223 add_messenger_callback_(add_messenger_callback),
224 delete_messenger_callback_(delete_messenger_callback) {
221 } 225 }
222 226
223 SSLConnectJob::~SSLConnectJob() {} 227 SSLConnectJob::~SSLConnectJob() {}
224 228
225 LoadState SSLConnectJob::GetLoadState() const { 229 LoadState SSLConnectJob::GetLoadState() const {
226 switch (next_state_) { 230 switch (next_state_) {
227 case STATE_TUNNEL_CONNECT_COMPLETE: 231 case STATE_TUNNEL_CONNECT_COMPLETE:
228 if (transport_socket_handle_->socket()) 232 if (transport_socket_handle_->socket())
229 return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL; 233 return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL;
230 // else, fall through. 234 // else, fall through.
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 connect_timing_.connect_start = socket_connect_timing.connect_start; 421 connect_timing_.connect_start = socket_connect_timing.connect_start;
418 connect_timing_.dns_start = socket_connect_timing.dns_start; 422 connect_timing_.dns_start = socket_connect_timing.dns_start;
419 connect_timing_.dns_end = socket_connect_timing.dns_end; 423 connect_timing_.dns_end = socket_connect_timing.dns_end;
420 } 424 }
421 425
422 ssl_socket_ = client_socket_factory_->CreateSSLClientSocket( 426 ssl_socket_ = client_socket_factory_->CreateSSLClientSocket(
423 transport_socket_handle_.Pass(), 427 transport_socket_handle_.Pass(),
424 params_->host_and_port(), 428 params_->host_and_port(),
425 params_->ssl_config(), 429 params_->ssl_config(),
426 context_); 430 context_);
431
432 // Retrieve an SSLConnectJobMessenger for this connection if needed.
433 if (!ssl_socket_->InSessionCache())
434 GetMessenger(ssl_socket_->GetSessionCacheKey());
435
427 return OK; 436 return OK;
428 } 437 }
429 438
430 int SSLConnectJob::DoCheckForResume() { 439 int SSLConnectJob::DoCheckForResume() {
431 next_state_ = STATE_SSL_CONNECT; 440 next_state_ = STATE_SSL_CONNECT;
441 if (ssl_socket_->InSessionCache())
442 return OK;
443
432 if (messenger_->CanProceed(ssl_socket_.get())) { 444 if (messenger_->CanProceed(ssl_socket_.get())) {
433 if (ssl_socket_->InSessionCache())
434 return OK;
435 messenger_->MonitorConnectionResult(ssl_socket_.get()); 445 messenger_->MonitorConnectionResult(ssl_socket_.get());
436 return OK; 446 return OK;
437 } 447 }
448
438 messenger_->AddPendingSocket( 449 messenger_->AddPendingSocket(
439 ssl_socket_.get(), 450 ssl_socket_.get(),
440 base::Bind(&net::SSLConnectJob::ResumeSSLConnection, 451 base::Bind(&net::SSLConnectJob::ResumeSSLConnection,
441 weak_factory_.GetWeakPtr())); 452 weak_factory_.GetWeakPtr()));
442 return ERR_IO_PENDING; 453 return ERR_IO_PENDING;
443 } 454 }
444 455
445 int SSLConnectJob::DoSSLConnect() { 456 int SSLConnectJob::DoSSLConnect() {
446 next_state_ = STATE_SSL_CONNECT_COMPLETE; 457 next_state_ = STATE_SSL_CONNECT_COMPLETE;
447 458
448 connect_timing_.ssl_start = base::TimeTicks::Now(); 459 connect_timing_.ssl_start = base::TimeTicks::Now();
449 460
450 return ssl_socket_->Connect(io_callback_); 461 return ssl_socket_->Connect(io_callback_);
451 } 462 }
452 463
453 int SSLConnectJob::DoSSLConnectComplete(int result) { 464 int SSLConnectJob::DoSSLConnectComplete(int result) {
454 connect_timing_.ssl_end = base::TimeTicks::Now(); 465 connect_timing_.ssl_end = base::TimeTicks::Now();
455 466
456 if (result != OK && SSLClientSocket::GetEnableConnectJobWaiting()) 467 if (SSLClientSocket::GetEnableConnectJobWaiting() && messenger_ != NULL) {
457 messenger_->OnJobFailed(); 468 if (result != OK)
458 469 messenger_->OnJobFailed();
470 else {
471 // If the connection was successful, determine if the job's messenger is
472 // still needed. If not, remove the messenger.
473 if (!messenger_->IsNeeded())
474 DeleteMessenger(ssl_socket_->GetSessionCacheKey());
475 }
476 }
459 SSLClientSocket::NextProtoStatus status = 477 SSLClientSocket::NextProtoStatus status =
460 SSLClientSocket::kNextProtoUnsupported; 478 SSLClientSocket::kNextProtoUnsupported;
461 std::string proto; 479 std::string proto;
462 std::string server_protos; 480 std::string server_protos;
463 // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket 481 // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket
464 // that hasn't had SSL_ImportFD called on it. If we get a certificate error 482 // that hasn't had SSL_ImportFD called on it. If we get a certificate error
465 // here, then we know that we called SSL_ImportFD. 483 // here, then we know that we called SSL_ImportFD.
466 if (result == OK || IsCertificateError(result)) 484 if (result == OK || IsCertificateError(result))
467 status = ssl_socket_->GetNextProto(&proto, &server_protos); 485 status = ssl_socket_->GetNextProto(&proto, &server_protos);
468 486
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 } 594 }
577 595
578 return result; 596 return result;
579 } 597 }
580 598
581 void SSLConnectJob::ResumeSSLConnection() { 599 void SSLConnectJob::ResumeSSLConnection() {
582 DCHECK_EQ(next_state_, STATE_SSL_CONNECT); 600 DCHECK_EQ(next_state_, STATE_SSL_CONNECT);
583 OnIOComplete(OK); 601 OnIOComplete(OK);
584 } 602 }
585 603
604 void SSLConnectJob::GetMessenger(std::string cache_key) {
605 messenger_ = add_messenger_callback_.Run(cache_key);
606 }
607
608 void SSLConnectJob::DeleteMessenger(std::string cache_key) {
609 delete_messenger_callback_.Run(cache_key);
610 messenger_ = NULL;
611 }
612
586 SSLConnectJob::State SSLConnectJob::GetInitialState( 613 SSLConnectJob::State SSLConnectJob::GetInitialState(
587 SSLSocketParams::ConnectionType connection_type) { 614 SSLSocketParams::ConnectionType connection_type) {
588 switch (connection_type) { 615 switch (connection_type) {
589 case SSLSocketParams::DIRECT: 616 case SSLSocketParams::DIRECT:
590 return STATE_TRANSPORT_CONNECT; 617 return STATE_TRANSPORT_CONNECT;
591 case SSLSocketParams::HTTP_PROXY: 618 case SSLSocketParams::HTTP_PROXY:
592 return STATE_TUNNEL_CONNECT; 619 return STATE_TUNNEL_CONNECT;
593 case SSLSocketParams::SOCKS_PROXY: 620 case SSLSocketParams::SOCKS_PROXY:
594 return STATE_SOCKS_CONNECT; 621 return STATE_SOCKS_CONNECT;
595 } 622 }
(...skipping 13 matching lines...) Expand all
609 ClientSocketFactory* client_socket_factory, 636 ClientSocketFactory* client_socket_factory,
610 HostResolver* host_resolver, 637 HostResolver* host_resolver,
611 const SSLClientSocketContext& context, 638 const SSLClientSocketContext& context,
612 NetLog* net_log) 639 NetLog* net_log)
613 : transport_pool_(transport_pool), 640 : transport_pool_(transport_pool),
614 socks_pool_(socks_pool), 641 socks_pool_(socks_pool),
615 http_proxy_pool_(http_proxy_pool), 642 http_proxy_pool_(http_proxy_pool),
616 client_socket_factory_(client_socket_factory), 643 client_socket_factory_(client_socket_factory),
617 host_resolver_(host_resolver), 644 host_resolver_(host_resolver),
618 context_(context), 645 context_(context),
619 net_log_(net_log), 646 net_log_(net_log) {
620 messenger_map_(new MessengerMap) {
621 base::TimeDelta max_transport_timeout = base::TimeDelta(); 647 base::TimeDelta max_transport_timeout = base::TimeDelta();
622 base::TimeDelta pool_timeout; 648 base::TimeDelta pool_timeout;
623 if (transport_pool_) 649 if (transport_pool_)
624 max_transport_timeout = transport_pool_->ConnectionTimeout(); 650 max_transport_timeout = transport_pool_->ConnectionTimeout();
625 if (socks_pool_) { 651 if (socks_pool_) {
626 pool_timeout = socks_pool_->ConnectionTimeout(); 652 pool_timeout = socks_pool_->ConnectionTimeout();
627 if (pool_timeout > max_transport_timeout) 653 if (pool_timeout > max_transport_timeout)
628 max_transport_timeout = pool_timeout; 654 max_transport_timeout = pool_timeout;
629 } 655 }
630 if (http_proxy_pool_) { 656 if (http_proxy_pool_) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 base_.AddLowerLayeredPool(socks_pool_); 708 base_.AddLowerLayeredPool(socks_pool_);
683 if (http_proxy_pool_) 709 if (http_proxy_pool_)
684 base_.AddLowerLayeredPool(http_proxy_pool_); 710 base_.AddLowerLayeredPool(http_proxy_pool_);
685 } 711 }
686 712
687 SSLClientSocketPool::~SSLClientSocketPool() { 713 SSLClientSocketPool::~SSLClientSocketPool() {
688 if (ssl_config_service_.get()) 714 if (ssl_config_service_.get())
689 ssl_config_service_->RemoveObserver(this); 715 ssl_config_service_->RemoveObserver(this);
690 } 716 }
691 717
692 scoped_ptr<ConnectJob> 718 SSLConnectJobMessenger*
693 SSLClientSocketPool::SSLConnectJobFactory::NewConnectJob( 719 SSLClientSocketPool::SSLConnectJobFactory::AddSSLConnectJobMessenger(
720 std::string cache_key) {
721 MessengerMap::const_iterator it = messenger_map_.find(cache_key);
722 if (it == messenger_map_.end()) {
723 std::pair<MessengerMap::iterator, bool> iter = messenger_map_.insert(
724 MessengerMap::value_type(cache_key, new SSLConnectJobMessenger()));
725 it = iter.first;
726 }
727 return it->second;
728 }
729
730 void SSLClientSocketPool::SSLConnectJobFactory::DeleteSSLConnectJobMessenger(
731 std::string cache_key) {
732 MessengerMap::iterator it = messenger_map_.find(cache_key);
733 delete it->second;
734 messenger_map_.erase(it);
735 }
736
737 scoped_ptr<ConnectJob> SSLClientSocketPool::SSLConnectJobFactory::NewConnectJob(
694 const std::string& group_name, 738 const std::string& group_name,
695 const PoolBase::Request& request, 739 const PoolBase::Request& request,
696 ConnectJob::Delegate* delegate) const { 740 ConnectJob::Delegate* delegate) {
697 SSLConnectJobMessenger* messenger; 741 return scoped_ptr<ConnectJob>(new SSLConnectJob(
698 std::string cache_key = SSLClientSocket::FormatSessionCacheKey( 742 group_name,
699 request.params()->host_and_port().ToString(), 743 request.priority(),
700 context_.ssl_session_cache_shard); 744 request.params(),
701 if (SSLClientSocket::GetEnableConnectJobWaiting()) { 745 ConnectionTimeout(),
702 MessengerMap::const_iterator it = messenger_map_->find(cache_key); 746 transport_pool_,
703 if (it == messenger_map_->end()) { 747 socks_pool_,
704 std::pair<MessengerMap::iterator, bool> iter = messenger_map_->insert( 748 http_proxy_pool_,
705 MessengerMap::value_type(cache_key, new SSLConnectJobMessenger())); 749 client_socket_factory_,
706 it = iter.first; 750 host_resolver_,
707 } 751 context_,
708 messenger = it->second; 752 NULL,
709 } else { 753 base::Bind(
710 messenger = NULL; 754 &SSLClientSocketPool::SSLConnectJobFactory::AddSSLConnectJobMessenger,
711 } 755 base::Unretained(this)),
712 756 base::Bind(&SSLClientSocketPool::SSLConnectJobFactory::
713 return scoped_ptr<ConnectJob>(new SSLConnectJob(group_name, 757 DeleteSSLConnectJobMessenger,
714 request.priority(), 758 base::Unretained(this)),
715 request.params(), 759 delegate,
716 ConnectionTimeout(), 760 net_log_));
717 transport_pool_,
718 socks_pool_,
719 http_proxy_pool_,
720 client_socket_factory_,
721 host_resolver_,
722 context_,
723 messenger,
724 delegate,
725 net_log_));
726 } 761 }
727 762
728 base::TimeDelta 763 base::TimeDelta
729 SSLClientSocketPool::SSLConnectJobFactory::ConnectionTimeout() const { 764 SSLClientSocketPool::SSLConnectJobFactory::ConnectionTimeout() const {
730 return timeout_; 765 return timeout_;
731 } 766 }
732 767
733 int SSLClientSocketPool::RequestSocket(const std::string& group_name, 768 int SSLClientSocketPool::RequestSocket(const std::string& group_name,
734 const void* socket_params, 769 const void* socket_params,
735 RequestPriority priority, 770 RequestPriority priority,
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 if (base_.CloseOneIdleSocket()) 874 if (base_.CloseOneIdleSocket())
840 return true; 875 return true;
841 return base_.CloseOneIdleConnectionInHigherLayeredPool(); 876 return base_.CloseOneIdleConnectionInHigherLayeredPool();
842 } 877 }
843 878
844 void SSLClientSocketPool::OnSSLConfigChanged() { 879 void SSLClientSocketPool::OnSSLConfigChanged() {
845 FlushWithError(ERR_NETWORK_CHANGED); 880 FlushWithError(ERR_NETWORK_CHANGED);
846 } 881 }
847 882
848 } // namespace net 883 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698