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

Side by Side Diff: google_apis/gcm/engine/connection_factory_impl.cc

Issue 205343003: [GCM] Add port 443 fallback logic and histograms (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update histogram enum Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "google_apis/gcm/engine/connection_factory_impl.h" 5 #include "google_apis/gcm/engine/connection_factory_impl.h"
6 6
7 #include "base/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/metrics/sparse_histogram.h" 9 #include "base/metrics/sparse_histogram.h"
10 #include "google_apis/gcm/engine/connection_handler_impl.h" 10 #include "google_apis/gcm/engine/connection_handler_impl.h"
(...skipping 23 matching lines...) Expand all
34 bool ShouldRestorePreviousBackoff(const base::TimeTicks& login_time, 34 bool ShouldRestorePreviousBackoff(const base::TimeTicks& login_time,
35 const base::TimeTicks& now_ticks) { 35 const base::TimeTicks& now_ticks) {
36 return !login_time.is_null() && 36 return !login_time.is_null() &&
37 now_ticks - login_time <= 37 now_ticks - login_time <=
38 base::TimeDelta::FromSeconds(kConnectionResetWindowSecs); 38 base::TimeDelta::FromSeconds(kConnectionResetWindowSecs);
39 } 39 }
40 40
41 } // namespace 41 } // namespace
42 42
43 ConnectionFactoryImpl::ConnectionFactoryImpl( 43 ConnectionFactoryImpl::ConnectionFactoryImpl(
44 const GURL& mcs_endpoint, 44 const std::vector<GURL>& mcs_endpoints,
45 const net::BackoffEntry::Policy& backoff_policy, 45 const net::BackoffEntry::Policy& backoff_policy,
46 scoped_refptr<net::HttpNetworkSession> network_session, 46 scoped_refptr<net::HttpNetworkSession> network_session,
47 net::NetLog* net_log) 47 net::NetLog* net_log)
48 : mcs_endpoint_(mcs_endpoint), 48 : mcs_endpoints_(mcs_endpoints),
49 next_endpoint_(0),
50 last_successful_endpoint_(0),
49 backoff_policy_(backoff_policy), 51 backoff_policy_(backoff_policy),
50 network_session_(network_session), 52 network_session_(network_session),
51 bound_net_log_( 53 bound_net_log_(
52 net::BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)), 54 net::BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)),
53 pac_request_(NULL), 55 pac_request_(NULL),
54 connecting_(false), 56 connecting_(false),
55 logging_in_(false), 57 logging_in_(false),
56 weak_ptr_factory_(this) { 58 weak_ptr_factory_(this) {
59 DCHECK_GE(mcs_endpoints_.size(), 1U);
57 } 60 }
58 61
59 ConnectionFactoryImpl::~ConnectionFactoryImpl() { 62 ConnectionFactoryImpl::~ConnectionFactoryImpl() {
60 if (pac_request_) { 63 if (pac_request_) {
61 network_session_->proxy_service()->CancelPacRequest(pac_request_); 64 network_session_->proxy_service()->CancelPacRequest(pac_request_);
62 pac_request_ = NULL; 65 pac_request_ = NULL;
63 } 66 }
64 } 67 }
65 68
66 void ConnectionFactoryImpl::Initialize( 69 void ConnectionFactoryImpl::Initialize(
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 // necessary, so no need to call again. 180 // necessary, so no need to call again.
178 } 181 }
179 182
180 void ConnectionFactoryImpl::OnIPAddressChanged() { 183 void ConnectionFactoryImpl::OnIPAddressChanged() {
181 DVLOG(1) << "IP Address changed, resetting backoff."; 184 DVLOG(1) << "IP Address changed, resetting backoff.";
182 backoff_entry_->Reset(); 185 backoff_entry_->Reset();
183 // Connect(..) should be retrying with backoff already if a connection is 186 // Connect(..) should be retrying with backoff already if a connection is
184 // necessary, so no need to call again. 187 // necessary, so no need to call again.
185 } 188 }
186 189
190 GURL ConnectionFactoryImpl::GetCurrentEndpoint() const {
191 // Note that IsEndpointReachable() returns false anytime connecting_ is true,
192 // so while connecting this always uses |next_endpoint_|.
193 if (IsEndpointReachable())
194 return mcs_endpoints_[last_successful_endpoint_];
195 return mcs_endpoints_[next_endpoint_];
196 }
197
187 void ConnectionFactoryImpl::ConnectImpl() { 198 void ConnectionFactoryImpl::ConnectImpl() {
188 DCHECK(connecting_); 199 DCHECK(connecting_);
189 DCHECK(!socket_handle_.socket()); 200 DCHECK(!socket_handle_.socket());
190 201
191 int status = network_session_->proxy_service()->ResolveProxy( 202 int status = network_session_->proxy_service()->ResolveProxy(
192 mcs_endpoint_, 203 GetCurrentEndpoint(),
193 &proxy_info_, 204 &proxy_info_,
194 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone, 205 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone,
195 weak_ptr_factory_.GetWeakPtr()), 206 weak_ptr_factory_.GetWeakPtr()),
196 &pac_request_, 207 &pac_request_,
197 bound_net_log_); 208 bound_net_log_);
198 if (status != net::ERR_IO_PENDING) 209 if (status != net::ERR_IO_PENDING)
199 OnProxyResolveDone(status); 210 OnProxyResolveDone(status);
200 } 211 }
201 212
202 void ConnectionFactoryImpl::InitHandler() { 213 void ConnectionFactoryImpl::InitHandler() {
(...skipping 24 matching lines...) Expand all
227 // not reconsidering a proxy) or returns ERR_IO_PENDING if it is considering 238 // not reconsidering a proxy) or returns ERR_IO_PENDING if it is considering
228 // another proxy. 239 // another proxy.
229 DCHECK_NE(result, net::OK); 240 DCHECK_NE(result, net::OK);
230 if (result == net::ERR_IO_PENDING) 241 if (result == net::ERR_IO_PENDING)
231 return; // Proxy reconsideration pending. Return. 242 return; // Proxy reconsideration pending. Return.
232 LOG(ERROR) << "Failed to connect to MCS endpoint with error " << result; 243 LOG(ERROR) << "Failed to connect to MCS endpoint with error " << result;
233 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", false); 244 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", false);
234 CloseSocket(); 245 CloseSocket();
235 backoff_entry_->InformOfRequest(false); 246 backoff_entry_->InformOfRequest(false);
236 UMA_HISTOGRAM_SPARSE_SLOWLY("GCM.ConnectionFailureErrorCode", result); 247 UMA_HISTOGRAM_SPARSE_SLOWLY("GCM.ConnectionFailureErrorCode", result);
248
249 // If there are other endpoints available, use the next endpoint on the
250 // subsequent retry.
251 next_endpoint_++;
252 if (next_endpoint_ >= mcs_endpoints_.size())
253 next_endpoint_ = 0;
237 Connect(); 254 Connect();
238 return; 255 return;
239 } 256 }
240 257
241 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", true); 258 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", true);
259 UMA_HISTOGRAM_COUNTS("GCM.ConnectionEndpoint", next_endpoint_);
260 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectedViaProxy",
261 !(proxy_info_.is_empty() || proxy_info_.is_direct()));
242 ReportSuccessfulProxyConnection(); 262 ReportSuccessfulProxyConnection();
243 263
264 // Reset the endpoint back to the default.
265 // TODO(zea): consider prioritizing endpoints more intelligently based on
266 // which ones succeed most for this client? Although that will affect
267 // measuring the success rate of the default endpoint vs fallback.
268 last_successful_endpoint_ = next_endpoint_;
269 next_endpoint_ = 0;
244 connecting_ = false; 270 connecting_ = false;
245 logging_in_ = true; 271 logging_in_ = true;
246 DVLOG(1) << "MCS endpoint socket connection success, starting login."; 272 DVLOG(1) << "MCS endpoint socket connection success, starting login.";
247 InitHandler(); 273 InitHandler();
248 } 274 }
249 275
250 void ConnectionFactoryImpl::ConnectionHandlerCallback(int result) { 276 void ConnectionFactoryImpl::ConnectionHandlerCallback(int result) {
251 DCHECK(!connecting_); 277 DCHECK(!connecting_);
252 if (result != net::OK) { 278 if (result != net::OK) {
253 // TODO(zea): Consider how to handle errors that may require some sort of 279 // TODO(zea): Consider how to handle errors that may require some sort of
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 // Failed to resolve proxy. Retry later. 319 // Failed to resolve proxy. Retry later.
294 OnConnectDone(status); 320 OnConnectDone(status);
295 return; 321 return;
296 } 322 }
297 323
298 DVLOG(1) << "Resolved proxy with PAC:" << proxy_info_.ToPacString(); 324 DVLOG(1) << "Resolved proxy with PAC:" << proxy_info_.ToPacString();
299 325
300 net::SSLConfig ssl_config; 326 net::SSLConfig ssl_config;
301 network_session_->ssl_config_service()->GetSSLConfig(&ssl_config); 327 network_session_->ssl_config_service()->GetSSLConfig(&ssl_config);
302 status = net::InitSocketHandleForTlsConnect( 328 status = net::InitSocketHandleForTlsConnect(
303 net::HostPortPair::FromURL(mcs_endpoint_), 329 net::HostPortPair::FromURL(GetCurrentEndpoint()),
304 network_session_.get(), 330 network_session_.get(),
305 proxy_info_, 331 proxy_info_,
306 ssl_config, 332 ssl_config,
307 ssl_config, 333 ssl_config,
308 net::kPrivacyModeDisabled, 334 net::kPrivacyModeDisabled,
309 bound_net_log_, 335 bound_net_log_,
310 &socket_handle_, 336 &socket_handle_,
311 base::Bind(&ConnectionFactoryImpl::OnConnectDone, 337 base::Bind(&ConnectionFactoryImpl::OnConnectDone,
312 weak_ptr_factory_.GetWeakPtr())); 338 weak_ptr_factory_.GetWeakPtr()));
313 if (status != net::ERR_IO_PENDING) 339 if (status != net::ERR_IO_PENDING)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 } 393 }
368 394
369 net::SSLConfig ssl_config; 395 net::SSLConfig ssl_config;
370 network_session_->ssl_config_service()->GetSSLConfig(&ssl_config); 396 network_session_->ssl_config_service()->GetSSLConfig(&ssl_config);
371 if (proxy_info_.is_https() && ssl_config.send_client_cert) { 397 if (proxy_info_.is_https() && ssl_config.send_client_cert) {
372 network_session_->ssl_client_auth_cache()->Remove( 398 network_session_->ssl_client_auth_cache()->Remove(
373 proxy_info_.proxy_server().host_port_pair()); 399 proxy_info_.proxy_server().host_port_pair());
374 } 400 }
375 401
376 int status = network_session_->proxy_service()->ReconsiderProxyAfterError( 402 int status = network_session_->proxy_service()->ReconsiderProxyAfterError(
377 mcs_endpoint_, &proxy_info_, 403 GetCurrentEndpoint(), &proxy_info_,
378 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone, 404 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone,
379 weak_ptr_factory_.GetWeakPtr()), 405 weak_ptr_factory_.GetWeakPtr()),
380 &pac_request_, 406 &pac_request_,
381 bound_net_log_); 407 bound_net_log_);
382 if (status == net::OK || status == net::ERR_IO_PENDING) { 408 if (status == net::OK || status == net::ERR_IO_PENDING) {
383 CloseSocket(); 409 CloseSocket();
384 } else { 410 } else {
385 // If ReconsiderProxyAfterError() failed synchronously, it means 411 // If ReconsiderProxyAfterError() failed synchronously, it means
386 // there was nothing left to fall-back to, so fail the transaction 412 // there was nothing left to fall-back to, so fail the transaction
387 // with the last connection error we got. 413 // with the last connection error we got.
(...skipping 22 matching lines...) Expand all
410 // the destroyed socket. 436 // the destroyed socket.
411 if (connection_handler_) 437 if (connection_handler_)
412 connection_handler_->Reset(); 438 connection_handler_->Reset();
413 439
414 if (socket_handle_.socket() && socket_handle_.socket()->IsConnected()) 440 if (socket_handle_.socket() && socket_handle_.socket()->IsConnected())
415 socket_handle_.socket()->Disconnect(); 441 socket_handle_.socket()->Disconnect();
416 socket_handle_.Reset(); 442 socket_handle_.Reset();
417 } 443 }
418 444
419 } // namespace gcm 445 } // namespace gcm
OLDNEW
« no previous file with comments | « google_apis/gcm/engine/connection_factory_impl.h ('k') | google_apis/gcm/engine/connection_factory_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698