Chromium Code Reviews| 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 "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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 base::MessageLoop::current()->PostDelayedTask( | 138 base::MessageLoop::current()->PostDelayedTask( |
| 139 FROM_HERE, | 139 FROM_HERE, |
| 140 base::Bind(&ConnectionFactoryImpl::ConnectWithBackoff, | 140 base::Bind(&ConnectionFactoryImpl::ConnectWithBackoff, |
| 141 weak_ptr_factory_.GetWeakPtr()), | 141 weak_ptr_factory_.GetWeakPtr()), |
| 142 backoff_entry_->GetTimeUntilRelease()); | 142 backoff_entry_->GetTimeUntilRelease()); |
| 143 return; | 143 return; |
| 144 } | 144 } |
| 145 | 145 |
| 146 DVLOG(1) << "Attempting connection to MCS endpoint."; | 146 DVLOG(1) << "Attempting connection to MCS endpoint."; |
| 147 waiting_for_backoff_ = false; | 147 waiting_for_backoff_ = false; |
| 148 // It's necessary to close the socket before attempting any new connection, | |
| 149 // otherwise it's possible to hit a use-after-free in the connection handler. | |
| 150 // crbug.com/462319 | |
| 151 CloseSocket(); | |
| 148 ConnectImpl(); | 152 ConnectImpl(); |
| 149 } | 153 } |
| 150 | 154 |
| 151 bool ConnectionFactoryImpl::IsEndpointReachable() const { | 155 bool ConnectionFactoryImpl::IsEndpointReachable() const { |
| 152 return connection_handler_ && connection_handler_->CanSendMessage(); | 156 return connection_handler_ && connection_handler_->CanSendMessage(); |
| 153 } | 157 } |
| 154 | 158 |
| 155 std::string ConnectionFactoryImpl::GetConnectionStateString() const { | 159 std::string ConnectionFactoryImpl::GetConnectionStateString() const { |
| 156 if (IsEndpointReachable()) | 160 if (IsEndpointReachable()) |
| 157 return "CONNECTED"; | 161 return "CONNECTED"; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 205 | 209 |
| 206 // Network changes get special treatment as they can trigger a one-off canary | 210 // Network changes get special treatment as they can trigger a one-off canary |
| 207 // request that bypasses backoff (but does nothing if a connection is in | 211 // request that bypasses backoff (but does nothing if a connection is in |
| 208 // progress). Other connection reset events can be ignored as a connection | 212 // progress). Other connection reset events can be ignored as a connection |
| 209 // is already awaiting backoff expiration. | 213 // is already awaiting backoff expiration. |
| 210 if (waiting_for_backoff_ && reason != NETWORK_CHANGE) { | 214 if (waiting_for_backoff_ && reason != NETWORK_CHANGE) { |
| 211 DVLOG(1) << "Backoff expiration pending, ignoring reset."; | 215 DVLOG(1) << "Backoff expiration pending, ignoring reset."; |
| 212 return; | 216 return; |
| 213 } | 217 } |
| 214 | 218 |
| 215 if (logging_in_) { | 219 if (reason == NETWORK_CHANGE) { |
| 220 // Canary attempts bypass backoff without resetting it. These will have no | |
| 221 // effect if we're already in the process of connecting. | |
|
fgorski
2015/03/04 17:43:04
To confirm. There is no need to close socket here,
Nicolas Zea
2015/03/04 17:56:42
We do it on line 204 above.
| |
| 222 ConnectImpl(); | |
| 223 return; | |
| 224 } else if (logging_in_) { | |
| 216 // Failures prior to login completion just reuse the existing backoff entry. | 225 // Failures prior to login completion just reuse the existing backoff entry. |
| 217 logging_in_ = false; | 226 logging_in_ = false; |
| 218 backoff_entry_->InformOfRequest(false); | 227 backoff_entry_->InformOfRequest(false); |
| 219 } else if (reason == LOGIN_FAILURE || | 228 } else if (reason == LOGIN_FAILURE || |
| 220 ShouldRestorePreviousBackoff(last_login_time_, NowTicks())) { | 229 ShouldRestorePreviousBackoff(last_login_time_, NowTicks())) { |
| 221 // Failures due to login, or within the reset window of a login, restore | 230 // Failures due to login, or within the reset window of a login, restore |
| 222 // the backoff entry that was saved off at login completion time. | 231 // the backoff entry that was saved off at login completion time. |
| 223 backoff_entry_.swap(previous_backoff_); | 232 backoff_entry_.swap(previous_backoff_); |
| 224 backoff_entry_->InformOfRequest(false); | 233 backoff_entry_->InformOfRequest(false); |
| 225 } else if (reason == NETWORK_CHANGE) { | |
| 226 ConnectImpl(); // Canary attempts bypass backoff without resetting it. | |
| 227 return; | |
| 228 } else { | 234 } else { |
| 229 // We shouldn't be in backoff in thise case. | 235 // We shouldn't be in backoff in thise case. |
| 230 DCHECK_EQ(0, backoff_entry_->failure_count()); | 236 DCHECK_EQ(0, backoff_entry_->failure_count()); |
| 231 } | 237 } |
| 232 | 238 |
| 233 // At this point the last login time has been consumed or deemed irrelevant, | 239 // At this point the last login time has been consumed or deemed irrelevant, |
| 234 // reset it. | 240 // reset it. |
| 235 last_login_time_ = base::TimeTicks(); | 241 last_login_time_ = base::TimeTicks(); |
| 236 | 242 |
| 237 Connect(); | 243 Connect(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 280 net::IPEndPoint ip_endpoint; | 286 net::IPEndPoint ip_endpoint; |
| 281 int result = socket_handle_.socket()->GetPeerAddress(&ip_endpoint); | 287 int result = socket_handle_.socket()->GetPeerAddress(&ip_endpoint); |
| 282 if (result != net::OK) | 288 if (result != net::OK) |
| 283 return net::IPEndPoint(); | 289 return net::IPEndPoint(); |
| 284 | 290 |
| 285 return ip_endpoint; | 291 return ip_endpoint; |
| 286 } | 292 } |
| 287 | 293 |
| 288 void ConnectionFactoryImpl::ConnectImpl() { | 294 void ConnectionFactoryImpl::ConnectImpl() { |
| 289 DCHECK(!IsEndpointReachable()); | 295 DCHECK(!IsEndpointReachable()); |
| 290 DCHECK(!socket_handle_.socket()); | 296 // TODO(zea): Make this a dcheck again. crbug.com/462319 |
| 297 CHECK(!socket_handle_.socket()); | |
| 291 | 298 |
| 292 // TODO(zea): if the network is offline, don't attempt to connect. | 299 // TODO(zea): if the network is offline, don't attempt to connect. |
| 293 // See crbug.com/396687 | 300 // See crbug.com/396687 |
| 294 | 301 |
| 295 connecting_ = true; | 302 connecting_ = true; |
| 296 GURL current_endpoint = GetCurrentEndpoint(); | 303 GURL current_endpoint = GetCurrentEndpoint(); |
| 297 recorder_->RecordConnectionInitiated(current_endpoint.host()); | 304 recorder_->RecordConnectionInitiated(current_endpoint.host()); |
| 298 RebuildNetworkSessionAuthCache(); | 305 RebuildNetworkSessionAuthCache(); |
| 299 int status = gcm_network_session_->proxy_service()->ResolveProxy( | 306 int status = gcm_network_session_->proxy_service()->ResolveProxy( |
| 300 current_endpoint, | 307 current_endpoint, |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 562 | 569 |
| 563 void ConnectionFactoryImpl::RebuildNetworkSessionAuthCache() { | 570 void ConnectionFactoryImpl::RebuildNetworkSessionAuthCache() { |
| 564 if (!http_network_session_.get() || !http_network_session_->http_auth_cache()) | 571 if (!http_network_session_.get() || !http_network_session_->http_auth_cache()) |
| 565 return; | 572 return; |
| 566 | 573 |
| 567 gcm_network_session_->http_auth_cache()->UpdateAllFrom( | 574 gcm_network_session_->http_auth_cache()->UpdateAllFrom( |
| 568 *http_network_session_->http_auth_cache()); | 575 *http_network_session_->http_auth_cache()); |
| 569 } | 576 } |
| 570 | 577 |
| 571 } // namespace gcm | 578 } // namespace gcm |
| OLD | NEW |