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

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

Issue 364943002: Makes waiting SSLConnectJobs use the message loops to resume their connection. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Changed OnSocketFailure callback to run directly & fixed comments. 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"
11 #include "base/metrics/sparse_histogram.h" 11 #include "base/metrics/sparse_histogram.h"
12 #include "base/thread_task_runner_handle.h"
12 #include "base/values.h" 13 #include "base/values.h"
13 #include "net/base/host_port_pair.h" 14 #include "net/base/host_port_pair.h"
14 #include "net/base/net_errors.h" 15 #include "net/base/net_errors.h"
15 #include "net/http/http_proxy_client_socket.h" 16 #include "net/http/http_proxy_client_socket.h"
16 #include "net/http/http_proxy_client_socket_pool.h" 17 #include "net/http/http_proxy_client_socket_pool.h"
17 #include "net/socket/client_socket_factory.h" 18 #include "net/socket/client_socket_factory.h"
18 #include "net/socket/client_socket_handle.h" 19 #include "net/socket/client_socket_handle.h"
19 #include "net/socket/socks_client_socket_pool.h" 20 #include "net/socket/socks_client_socket_pool.h"
20 #include "net/socket/ssl_client_socket.h" 21 #include "net/socket/ssl_client_socket.h"
21 #include "net/socket/transport_client_socket_pool.h" 22 #include "net/socket/transport_client_socket_pool.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 DCHECK_EQ(GetConnectionType(), SOCKS_PROXY); 88 DCHECK_EQ(GetConnectionType(), SOCKS_PROXY);
88 return socks_proxy_params_; 89 return socks_proxy_params_;
89 } 90 }
90 91
91 const scoped_refptr<HttpProxySocketParams>& 92 const scoped_refptr<HttpProxySocketParams>&
92 SSLSocketParams::GetHttpProxyConnectionParams() const { 93 SSLSocketParams::GetHttpProxyConnectionParams() const {
93 DCHECK_EQ(GetConnectionType(), HTTP_PROXY); 94 DCHECK_EQ(GetConnectionType(), HTTP_PROXY);
94 return http_proxy_params_; 95 return http_proxy_params_;
95 } 96 }
96 97
98 SSLConnectJobMessenger::SSLConnectJobMessenger() : weak_factory_(this) {
99 }
100
97 bool SSLConnectJobMessenger::CanProceed(SSLClientSocket* ssl_socket) { 101 bool SSLConnectJobMessenger::CanProceed(SSLClientSocket* ssl_socket) {
98 // If the session is in the session cache, or there are no connecting 102 // If the session is in the session cache, or there are no connecting
99 // sockets allow the connection to proceed. 103 // sockets allow the connection to proceed.
100 if (ssl_socket->InSessionCache() || connecting_sockets_.empty()) { 104 if (ssl_socket->InSessionCache() || connecting_sockets_.empty()) {
101 return true; 105 return true;
102 } 106 }
103 return false; 107 return false;
104 } 108 }
105 109
106 void SSLConnectJobMessenger::MonitorConnectionResult( 110 void SSLConnectJobMessenger::MonitorConnectionResult(
107 SSLClientSocket* ssl_socket) { 111 SSLClientSocket* ssl_socket) {
108 connecting_sockets_.push_back(ssl_socket); 112 connecting_sockets_.push_back(ssl_socket);
109 ssl_socket->SetIsLeader(); 113 ssl_socket->SetIsLeader();
110 ssl_socket->SetSocketFailureCallback( 114 // SSLConnectJobMessenger weak pointers are used here to ensure that
111 base::Bind(&SSLConnectJobMessenger::OnJobFailed, base::Unretained(this))); 115 // tasks posted with these callbacks are deregistered if the
116 // SSLConnectJobMessenger should become invalid before they're run.
117 ssl_socket->SetSocketFailureCallback(base::Bind(
118 &SSLConnectJobMessenger::OnJobFailed, weak_factory_.GetWeakPtr()));
112 ssl_socket->WatchSessionForCompletion(base::Bind( 119 ssl_socket->WatchSessionForCompletion(base::Bind(
113 &SSLConnectJobMessenger::OnJobSucceeded, base::Unretained(this))); 120 &SSLConnectJobMessenger::OnJobSucceeded, weak_factory_.GetWeakPtr()));
114 } 121 }
115 122
116 void SSLConnectJobMessenger::AddPendingSocket(SSLClientSocket* socket, 123 void SSLConnectJobMessenger::AddPendingSocket(SSLClientSocket* socket,
117 const base::Closure& callback) { 124 const base::Closure& callback) {
118 pending_sockets_and_callbacks_.push_back(SocketAndCallback(socket, callback)); 125 pending_sockets_and_callbacks_.push_back(SocketAndCallback(socket, callback));
119 } 126 }
120 127
121 void SSLConnectJobMessenger::OnJobSucceeded() { 128 void SSLConnectJobMessenger::OnJobSucceeded() {
122 SSLPendingSocketsAndCallbacks temp_list = pending_sockets_and_callbacks_; 129 SSLPendingSocketsAndCallbacks temp_list = pending_sockets_and_callbacks_;
123 pending_sockets_and_callbacks_.clear(); 130 pending_sockets_and_callbacks_.clear();
124 connecting_sockets_.clear(); 131 connecting_sockets_.clear();
125 RunAllJobs(temp_list); 132 RunAllJobs(temp_list);
126 } 133 }
127 134
128 void SSLConnectJobMessenger::OnJobFailed() { 135 void SSLConnectJobMessenger::OnJobFailed() {
129 if (pending_sockets_and_callbacks_.empty()) 136 base::Closure callback = base::Bind(&SSLConnectJobMessenger::ConnectNewLeader,
137 weak_factory_.GetWeakPtr());
138 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
wtc 2014/07/14 22:39:18 I still think we can run ConnectNewLeader directly
Ryan Sleevi 2014/07/15 00:48:11 Wan-Teh: I'm not sure we can. Happy to follow-up o
wtc 2014/07/15 21:27:08 Ryan and I discussed this in person. You can go ah
wtc 2014/07/16 21:48:12 The purpose of the PostTask should be explained wi
mshelley 2014/07/17 16:28:03 Done.
139 }
140
141 void SSLConnectJobMessenger::ConnectNewLeader() {
142 connecting_sockets_.erase(connecting_sockets_.begin());
143 std::vector<SocketAndCallback>::iterator it =
144 pending_sockets_and_callbacks_.begin();
145
146 SSLClientSocket* ssl_socket = it->socket;
147 base::Closure& callback = it->callback;
148
149 // If there were no valid pending sockets, return.
150 if (it == pending_sockets_and_callbacks_.end())
130 return; 151 return;
wtc 2014/07/14 22:39:18 BUG: Check |it| first, before dereferencing |it|:
mshelley 2014/07/17 16:28:03 Done.
131 base::Closure callback = pending_sockets_and_callbacks_[0].callback; 152
132 connecting_sockets_.erase(connecting_sockets_.begin()); 153 pending_sockets_and_callbacks_.erase(it);
133 SSLClientSocket* ssl_socket = pending_sockets_and_callbacks_[0].socket; 154
134 pending_sockets_and_callbacks_.erase(pending_sockets_and_callbacks_.begin());
135 MonitorConnectionResult(ssl_socket); 155 MonitorConnectionResult(ssl_socket);
136 callback.Run(); 156 callback.Run();
wtc 2014/07/14 23:57:31 I believe that if the SSLClientSocket destructor (
mshelley 2014/07/17 16:28:03 Done.
137 } 157 }
138 158
139 void SSLConnectJobMessenger::RunAllJobs( 159 void SSLConnectJobMessenger::RunAllJobs(
140 std::vector<SocketAndCallback>& pending_sockets_and_callbacks) { 160 std::vector<SocketAndCallback>& pending_sockets_and_callbacks) {
161 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
162 base::ThreadTaskRunnerHandle::Get();
Ryan Sleevi 2014/07/16 21:54:43 Use a SequencedTaskRunner here instead. Or just Ta
mshelley 2014/07/17 16:28:03 Done.
141 for (std::vector<SocketAndCallback>::const_iterator it = 163 for (std::vector<SocketAndCallback>::const_iterator it =
142 pending_sockets_and_callbacks.begin(); 164 pending_sockets_and_callbacks.begin();
143 it != pending_sockets_and_callbacks.end(); 165 it != pending_sockets_and_callbacks.end();
144 ++it) 166 ++it) {
145 it->callback.Run(); 167 task_runner->PostTask(FROM_HERE, it->callback);
wtc 2014/07/16 21:48:12 Based on my understanding of the problem (the some
Ryan Sleevi 2014/07/16 21:54:43 I think this requires some clarifications, and as
mshelley 2014/07/17 16:28:03 So if I understand correctly, the reason to contin
wtc 2014/07/18 01:31:57 It turns out that you can do "delete this;" in a m
168 }
146 } 169 }
147 170
148 // Timeout for the SSL handshake portion of the connect. 171 // Timeout for the SSL handshake portion of the connect.
149 static const int kSSLHandshakeTimeoutInSeconds = 30; 172 static const int kSSLHandshakeTimeoutInSeconds = 30;
150 173
151 SSLConnectJob::SSLConnectJob(const std::string& group_name, 174 SSLConnectJob::SSLConnectJob(const std::string& group_name,
152 RequestPriority priority, 175 RequestPriority priority,
153 const scoped_refptr<SSLSocketParams>& params, 176 const scoped_refptr<SSLSocketParams>& params,
154 const base::TimeDelta& timeout_duration, 177 const base::TimeDelta& timeout_duration,
155 TransportClientSocketPool* transport_pool, 178 TransportClientSocketPool* transport_pool,
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 435
413 connect_timing_.ssl_start = base::TimeTicks::Now(); 436 connect_timing_.ssl_start = base::TimeTicks::Now();
414 437
415 return ssl_socket_->Connect(io_callback_); 438 return ssl_socket_->Connect(io_callback_);
416 } 439 }
417 440
418 int SSLConnectJob::DoSSLConnectComplete(int result) { 441 int SSLConnectJob::DoSSLConnectComplete(int result) {
419 connect_timing_.ssl_end = base::TimeTicks::Now(); 442 connect_timing_.ssl_end = base::TimeTicks::Now();
420 443
421 if (result != OK && SSLClientSocketPool::GetEnableConnectJobWaiting()) 444 if (result != OK && SSLClientSocketPool::GetEnableConnectJobWaiting())
422 messenger_->OnJobFailed(); 445 messenger_->OnJobFailed();
wtc 2014/07/14 23:57:31 Delete these two lines. Then OnJobFailed can be pr
mshelley 2014/07/17 16:28:03 Done.
423 446
424 SSLClientSocket::NextProtoStatus status = 447 SSLClientSocket::NextProtoStatus status =
425 SSLClientSocket::kNextProtoUnsupported; 448 SSLClientSocket::kNextProtoUnsupported;
426 std::string proto; 449 std::string proto;
427 std::string server_protos; 450 std::string server_protos;
428 // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket 451 // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket
429 // that hasn't had SSL_ImportFD called on it. If we get a certificate error 452 // that hasn't had SSL_ImportFD called on it. If we get a certificate error
430 // here, then we know that we called SSL_ImportFD. 453 // here, then we know that we called SSL_ImportFD.
431 if (result == OK || IsCertificateError(result)) 454 if (result == OK || IsCertificateError(result))
432 status = ssl_socket_->GetNextProto(&proto, &server_protos); 455 status = ssl_socket_->GetNextProto(&proto, &server_protos);
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 // static 840 // static
818 bool SSLClientSocketPool::GetEnableConnectJobWaiting() { 841 bool SSLClientSocketPool::GetEnableConnectJobWaiting() {
819 return enable_connect_job_waiting_; 842 return enable_connect_job_waiting_;
820 } 843 }
821 844
822 void SSLClientSocketPool::OnSSLConfigChanged() { 845 void SSLClientSocketPool::OnSSLConfigChanged() {
823 FlushWithError(ERR_NETWORK_CHANGED); 846 FlushWithError(ERR_NETWORK_CHANGED);
824 } 847 }
825 848
826 } // namespace net 849 } // namespace net
OLDNEW
« net/socket/ssl_client_socket_pool.h ('K') | « net/socket/ssl_client_socket_pool.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698