| OLD | NEW |
| 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 <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 | 117 |
| 118 if (connecting_ || waiting_for_backoff_) | 118 if (connecting_ || waiting_for_backoff_) |
| 119 return; // Connection attempt already in progress or pending. | 119 return; // Connection attempt already in progress or pending. |
| 120 | 120 |
| 121 if (IsEndpointReachable()) | 121 if (IsEndpointReachable()) |
| 122 return; // Already connected. | 122 return; // Already connected. |
| 123 | 123 |
| 124 ConnectWithBackoff(); | 124 ConnectWithBackoff(); |
| 125 } | 125 } |
| 126 | 126 |
| 127 ConnectionEventTracker* ConnectionFactoryImpl::GetEventTrackerForTesting() { |
| 128 return &event_tracker_; |
| 129 } |
| 130 |
| 127 void ConnectionFactoryImpl::ConnectWithBackoff() { | 131 void ConnectionFactoryImpl::ConnectWithBackoff() { |
| 128 // If a canary managed to connect while a backoff expiration was pending, | 132 // If a canary managed to connect while a backoff expiration was pending, |
| 129 // just cleanup the internal state. | 133 // just cleanup the internal state. |
| 130 if (connecting_ || logging_in_ || IsEndpointReachable()) { | 134 if (connecting_ || logging_in_ || IsEndpointReachable()) { |
| 131 waiting_for_backoff_ = false; | 135 waiting_for_backoff_ = false; |
| 132 return; | 136 return; |
| 133 } | 137 } |
| 134 | 138 |
| 135 if (backoff_entry_->ShouldRejectRequest()) { | 139 if (backoff_entry_->ShouldRejectRequest()) { |
| 136 DVLOG(1) << "Delaying MCS endpoint connection for " | 140 DVLOG(1) << "Delaying MCS endpoint connection for " |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 if (!last_login_time_.is_null()) { | 202 if (!last_login_time_.is_null()) { |
| 199 UMA_HISTOGRAM_CUSTOM_TIMES("GCM.ConnectionUpTime", | 203 UMA_HISTOGRAM_CUSTOM_TIMES("GCM.ConnectionUpTime", |
| 200 NowTicks() - last_login_time_, | 204 NowTicks() - last_login_time_, |
| 201 base::TimeDelta::FromSeconds(1), | 205 base::TimeDelta::FromSeconds(1), |
| 202 base::TimeDelta::FromHours(24), | 206 base::TimeDelta::FromHours(24), |
| 203 50); | 207 50); |
| 204 // |last_login_time_| will be reset below, before attempting the new | 208 // |last_login_time_| will be reset below, before attempting the new |
| 205 // connection. | 209 // connection. |
| 206 } | 210 } |
| 207 | 211 |
| 212 if (logging_in_) |
| 213 event_tracker_.ConnectionLoginFailed(); |
| 214 event_tracker_.EndConnectionAttempt(); |
| 215 |
| 208 CloseSocket(); | 216 CloseSocket(); |
| 209 DCHECK(!IsEndpointReachable()); | 217 DCHECK(!IsEndpointReachable()); |
| 210 | 218 |
| 211 // TODO(zea): if the network is offline, don't attempt to connect. | 219 // TODO(zea): if the network is offline, don't attempt to connect. |
| 212 // See crbug.com/396687 | 220 // See crbug.com/396687 |
| 213 | 221 |
| 214 // Network changes get special treatment as they can trigger a one-off canary | 222 // Network changes get special treatment as they can trigger a one-off canary |
| 215 // request that bypasses backoff (but does nothing if a connection is in | 223 // request that bypasses backoff (but does nothing if a connection is in |
| 216 // progress). Other connection reset events can be ignored as a connection | 224 // progress). Other connection reset events can be ignored as a connection |
| 217 // is already awaiting backoff expiration. | 225 // is already awaiting backoff expiration. |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 | 297 |
| 290 net::IPEndPoint ip_endpoint; | 298 net::IPEndPoint ip_endpoint; |
| 291 int result = socket_handle_.socket()->GetPeerAddress(&ip_endpoint); | 299 int result = socket_handle_.socket()->GetPeerAddress(&ip_endpoint); |
| 292 if (result != net::OK) | 300 if (result != net::OK) |
| 293 return net::IPEndPoint(); | 301 return net::IPEndPoint(); |
| 294 | 302 |
| 295 return ip_endpoint; | 303 return ip_endpoint; |
| 296 } | 304 } |
| 297 | 305 |
| 298 void ConnectionFactoryImpl::ConnectImpl() { | 306 void ConnectionFactoryImpl::ConnectImpl() { |
| 307 event_tracker_.StartConnectionAttempt(); |
| 308 StartConnection(); |
| 309 } |
| 310 |
| 311 void ConnectionFactoryImpl::StartConnection() { |
| 299 DCHECK(!IsEndpointReachable()); | 312 DCHECK(!IsEndpointReachable()); |
| 300 // TODO(zea): Make this a dcheck again. crbug.com/462319 | 313 // TODO(zea): Make this a dcheck again. crbug.com/462319 |
| 301 CHECK(!socket_handle_.socket()); | 314 CHECK(!socket_handle_.socket()); |
| 302 | 315 |
| 303 // TODO(zea): if the network is offline, don't attempt to connect. | 316 // TODO(zea): if the network is offline, don't attempt to connect. |
| 304 // See crbug.com/396687 | 317 // See crbug.com/396687 |
| 305 | 318 |
| 306 connecting_ = true; | 319 connecting_ = true; |
| 307 GURL current_endpoint = GetCurrentEndpoint(); | 320 GURL current_endpoint = GetCurrentEndpoint(); |
| 308 recorder_->RecordConnectionInitiated(current_endpoint.host()); | 321 recorder_->RecordConnectionInitiated(current_endpoint.host()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 319 if (status != net::ERR_IO_PENDING) | 332 if (status != net::ERR_IO_PENDING) |
| 320 OnProxyResolveDone(status); | 333 OnProxyResolveDone(status); |
| 321 } | 334 } |
| 322 | 335 |
| 323 void ConnectionFactoryImpl::InitHandler() { | 336 void ConnectionFactoryImpl::InitHandler() { |
| 324 // May be null in tests. | 337 // May be null in tests. |
| 325 mcs_proto::LoginRequest login_request; | 338 mcs_proto::LoginRequest login_request; |
| 326 if (!request_builder_.is_null()) { | 339 if (!request_builder_.is_null()) { |
| 327 request_builder_.Run(&login_request); | 340 request_builder_.Run(&login_request); |
| 328 DCHECK(login_request.IsInitialized()); | 341 DCHECK(login_request.IsInitialized()); |
| 342 event_tracker_.WriteToLoginRequest(&login_request); |
| 329 } | 343 } |
| 330 | 344 |
| 331 connection_handler_->Init(login_request, socket_handle_.socket()); | 345 connection_handler_->Init(login_request, socket_handle_.socket()); |
| 332 } | 346 } |
| 333 | 347 |
| 334 std::unique_ptr<net::BackoffEntry> ConnectionFactoryImpl::CreateBackoffEntry( | 348 std::unique_ptr<net::BackoffEntry> ConnectionFactoryImpl::CreateBackoffEntry( |
| 335 const net::BackoffEntry::Policy* const policy) { | 349 const net::BackoffEntry::Policy* const policy) { |
| 336 return std::unique_ptr<net::BackoffEntry>(new net::BackoffEntry(policy)); | 350 return std::unique_ptr<net::BackoffEntry>(new net::BackoffEntry(policy)); |
| 337 } | 351 } |
| 338 | 352 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 364 DCHECK_NE(result, net::OK); | 378 DCHECK_NE(result, net::OK); |
| 365 if (result == net::ERR_IO_PENDING) | 379 if (result == net::ERR_IO_PENDING) |
| 366 return; // Proxy reconsideration pending. Return. | 380 return; // Proxy reconsideration pending. Return. |
| 367 LOG(ERROR) << "Failed to connect to MCS endpoint with error " << result; | 381 LOG(ERROR) << "Failed to connect to MCS endpoint with error " << result; |
| 368 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", false); | 382 UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", false); |
| 369 recorder_->RecordConnectionFailure(result); | 383 recorder_->RecordConnectionFailure(result); |
| 370 CloseSocket(); | 384 CloseSocket(); |
| 371 backoff_entry_->InformOfRequest(false); | 385 backoff_entry_->InformOfRequest(false); |
| 372 UMA_HISTOGRAM_SPARSE_SLOWLY("GCM.ConnectionFailureErrorCode", result); | 386 UMA_HISTOGRAM_SPARSE_SLOWLY("GCM.ConnectionFailureErrorCode", result); |
| 373 | 387 |
| 388 event_tracker_.ConnectionAttemptFailed(result); |
| 389 event_tracker_.EndConnectionAttempt(); |
| 390 |
| 374 // If there are other endpoints available, use the next endpoint on the | 391 // If there are other endpoints available, use the next endpoint on the |
| 375 // subsequent retry. | 392 // subsequent retry. |
| 376 next_endpoint_++; | 393 next_endpoint_++; |
| 377 if (next_endpoint_ >= mcs_endpoints_.size()) | 394 if (next_endpoint_ >= mcs_endpoints_.size()) |
| 378 next_endpoint_ = 0; | 395 next_endpoint_ = 0; |
| 379 connecting_ = false; | 396 connecting_ = false; |
| 380 Connect(); | 397 Connect(); |
| 381 return; | 398 return; |
| 382 } | 399 } |
| 383 | 400 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 412 | 429 |
| 413 // Handshake complete, reset backoff. If the login failed with an error, | 430 // Handshake complete, reset backoff. If the login failed with an error, |
| 414 // the client should invoke SignalConnectionReset(LOGIN_FAILURE), which will | 431 // the client should invoke SignalConnectionReset(LOGIN_FAILURE), which will |
| 415 // restore the previous backoff. | 432 // restore the previous backoff. |
| 416 DVLOG(1) << "Handshake complete."; | 433 DVLOG(1) << "Handshake complete."; |
| 417 last_login_time_ = NowTicks(); | 434 last_login_time_ = NowTicks(); |
| 418 previous_backoff_.swap(backoff_entry_); | 435 previous_backoff_.swap(backoff_entry_); |
| 419 backoff_entry_->Reset(); | 436 backoff_entry_->Reset(); |
| 420 logging_in_ = false; | 437 logging_in_ = false; |
| 421 | 438 |
| 439 event_tracker_.ConnectionAttemptSucceeded(); |
| 440 |
| 422 if (listener_) | 441 if (listener_) |
| 423 listener_->OnConnected(GetCurrentEndpoint(), GetPeerIP()); | 442 listener_->OnConnected(GetCurrentEndpoint(), GetPeerIP()); |
| 424 } | 443 } |
| 425 | 444 |
| 426 // This has largely been copied from | 445 // This has largely been copied from |
| 427 // HttpStreamFactoryImpl::Job::DoResolveProxyComplete. This should be | 446 // HttpStreamFactoryImpl::Job::DoResolveProxyComplete. This should be |
| 428 // refactored into some common place. | 447 // refactored into some common place. |
| 429 void ConnectionFactoryImpl::OnProxyResolveDone(int status) { | 448 void ConnectionFactoryImpl::OnProxyResolveDone(int status) { |
| 430 pac_request_ = NULL; | 449 pac_request_ = NULL; |
| 431 DVLOG(1) << "Proxy resolution status: " << status; | 450 DVLOG(1) << "Proxy resolution status: " << status; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 | 592 |
| 574 void ConnectionFactoryImpl::RebuildNetworkSessionAuthCache() { | 593 void ConnectionFactoryImpl::RebuildNetworkSessionAuthCache() { |
| 575 if (!http_network_session_ || !http_network_session_->http_auth_cache()) | 594 if (!http_network_session_ || !http_network_session_->http_auth_cache()) |
| 576 return; | 595 return; |
| 577 | 596 |
| 578 gcm_network_session_->http_auth_cache()->UpdateAllFrom( | 597 gcm_network_session_->http_auth_cache()->UpdateAllFrom( |
| 579 *http_network_session_->http_auth_cache()); | 598 *http_network_session_->http_auth_cache()); |
| 580 } | 599 } |
| 581 | 600 |
| 582 } // namespace gcm | 601 } // namespace gcm |
| OLD | NEW |