Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/transport_client_socket_pool.h" | 5 #include "net/socket/transport_client_socket_pool.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 return LOAD_STATE_IDLE; | 230 return LOAD_STATE_IDLE; |
| 231 } | 231 } |
| 232 NOTREACHED(); | 232 NOTREACHED(); |
| 233 return LOAD_STATE_IDLE; | 233 return LOAD_STATE_IDLE; |
| 234 } | 234 } |
| 235 | 235 |
| 236 void TransportConnectJob::GetAdditionalErrorState(ClientSocketHandle* handle) { | 236 void TransportConnectJob::GetAdditionalErrorState(ClientSocketHandle* handle) { |
| 237 // If hostname resolution failed, record an empty endpoint and the result. | 237 // If hostname resolution failed, record an empty endpoint and the result. |
| 238 // If the actual socket Connect call failed, record the result and the last | 238 // If the actual socket Connect call failed, record the result and the last |
| 239 // address attempted. | 239 // address attempted. |
| 240 // TODO(ttuttle): Plumb into the socket layer and record *all* attempts. | |
| 241 ConnectionAttempts attempts; | 240 ConnectionAttempts attempts; |
| 242 if (resolve_result_ != OK) { | 241 if (resolve_result_ != OK) { |
| 243 DCHECK_EQ(0u, helper_.addresses().size()); | 242 DCHECK_EQ(0u, helper_.addresses().size()); |
| 244 attempts.push_back(ConnectionAttempt(IPEndPoint(), resolve_result_)); | 243 attempts.push_back(ConnectionAttempt(IPEndPoint(), resolve_result_)); |
| 245 } else if (connect_result_ != OK) { | 244 } else if (connect_result_ != OK) { |
| 246 DCHECK_LT(0u, helper_.addresses().size()); | 245 attempts.insert(attempts.begin(), connection_attempts_.begin(), |
| 247 attempts.push_back( | 246 connection_attempts_.end()); |
| 248 ConnectionAttempt(helper_.addresses().back(), connect_result_)); | 247 attempts.insert(attempts.begin(), fallback_connection_attempts_.begin(), |
| 248 fallback_connection_attempts_.end()); | |
| 249 } | 249 } |
| 250 handle->set_connection_attempts(attempts); | 250 handle->set_connection_attempts(attempts); |
| 251 } | 251 } |
| 252 | 252 |
| 253 // static | 253 // static |
| 254 void TransportConnectJob::MakeAddressListStartWithIPv4(AddressList* list) { | 254 void TransportConnectJob::MakeAddressListStartWithIPv4(AddressList* list) { |
| 255 for (AddressList::iterator i = list->begin(); i != list->end(); ++i) { | 255 for (AddressList::iterator i = list->begin(); i != list->end(); ++i) { |
| 256 if (i->GetFamily() == ADDRESS_FAMILY_IPV4) { | 256 if (i->GetFamily() == ADDRESS_FAMILY_IPV4) { |
| 257 std::rotate(list->begin(), i, list->end()); | 257 std::rotate(list->begin(), i, list->end()); |
| 258 break; | 258 break; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 323 base::TimeDelta::FromMilliseconds( | 323 base::TimeDelta::FromMilliseconds( |
| 324 TransportConnectJobHelper::kIPv6FallbackTimerInMs), | 324 TransportConnectJobHelper::kIPv6FallbackTimerInMs), |
| 325 this, | 325 this, |
| 326 &TransportConnectJob::DoIPv6FallbackTransportConnect); | 326 &TransportConnectJob::DoIPv6FallbackTransportConnect); |
| 327 } | 327 } |
| 328 return rv; | 328 return rv; |
| 329 } | 329 } |
| 330 | 330 |
| 331 int TransportConnectJob::DoTransportConnectComplete(int result) { | 331 int TransportConnectJob::DoTransportConnectComplete(int result) { |
| 332 if (result == OK) { | 332 if (result == OK) { |
| 333 // Success will be returned via the main socket, so also include connection | |
| 334 // attempts made on the fallback socket. | |
|
Randy Smith (Not in Mondays)
2015/05/12 20:11:09
Acknowledgement of ugly hack in comment? :-} :-J.
Deprecated (see juliatuttle)
2015/05/13 18:22:28
Done.
| |
| 335 if (fallback_transport_socket_) { | |
| 336 ConnectionAttempts fallback_attempts; | |
| 337 fallback_transport_socket_->GetConnectionAttempts(&fallback_attempts); | |
| 338 transport_socket_->AddConnectionAttempts(fallback_attempts); | |
| 339 } | |
| 340 | |
| 333 bool is_ipv4 = | 341 bool is_ipv4 = |
| 334 helper_.addresses().front().GetFamily() == ADDRESS_FAMILY_IPV4; | 342 helper_.addresses().front().GetFamily() == ADDRESS_FAMILY_IPV4; |
| 335 TransportConnectJobHelper::ConnectionLatencyHistogram race_result = | 343 TransportConnectJobHelper::ConnectionLatencyHistogram race_result = |
| 336 TransportConnectJobHelper::CONNECTION_LATENCY_UNKNOWN; | 344 TransportConnectJobHelper::CONNECTION_LATENCY_UNKNOWN; |
| 337 if (is_ipv4) { | 345 if (is_ipv4) { |
| 338 race_result = TransportConnectJobHelper::CONNECTION_LATENCY_IPV4_NO_RACE; | 346 race_result = TransportConnectJobHelper::CONNECTION_LATENCY_IPV4_NO_RACE; |
| 339 } else { | 347 } else { |
| 340 if (AddressListOnlyContainsIPv6(helper_.addresses())) { | 348 if (AddressListOnlyContainsIPv6(helper_.addresses())) { |
| 341 race_result = TransportConnectJobHelper::CONNECTION_LATENCY_IPV6_SOLO; | 349 race_result = TransportConnectJobHelper::CONNECTION_LATENCY_IPV6_SOLO; |
| 342 } else { | 350 } else { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 371 100); | 379 100); |
| 372 break; | 380 break; |
| 373 default: | 381 default: |
| 374 NOTREACHED(); | 382 NOTREACHED(); |
| 375 break; | 383 break; |
| 376 } | 384 } |
| 377 | 385 |
| 378 SetSocket(transport_socket_.Pass()); | 386 SetSocket(transport_socket_.Pass()); |
| 379 fallback_timer_.Stop(); | 387 fallback_timer_.Stop(); |
| 380 } else { | 388 } else { |
| 389 // Failure will be returned via |GetAdditionalErrorState|, so save | |
| 390 // connection attempts from both sockets for use there. | |
| 391 CopyConnectionAttemptsFromClientSocketHandles(); | |
| 392 | |
| 381 // Be a bit paranoid and kill off the fallback members to prevent reuse. | 393 // Be a bit paranoid and kill off the fallback members to prevent reuse. |
| 382 fallback_transport_socket_.reset(); | 394 fallback_transport_socket_.reset(); |
| 383 fallback_addresses_.reset(); | 395 fallback_addresses_.reset(); |
| 384 } | 396 } |
| 385 | 397 |
| 386 connect_result_ = result; | 398 connect_result_ = result; |
| 387 | 399 |
| 388 return result; | 400 return result; |
| 389 } | 401 } |
| 390 | 402 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 421 NOTREACHED(); | 433 NOTREACHED(); |
| 422 return; | 434 return; |
| 423 } | 435 } |
| 424 | 436 |
| 425 DCHECK_NE(ERR_IO_PENDING, result); | 437 DCHECK_NE(ERR_IO_PENDING, result); |
| 426 DCHECK(fallback_transport_socket_.get()); | 438 DCHECK(fallback_transport_socket_.get()); |
| 427 DCHECK(fallback_addresses_.get()); | 439 DCHECK(fallback_addresses_.get()); |
| 428 | 440 |
| 429 if (result == OK) { | 441 if (result == OK) { |
| 430 DCHECK(!fallback_connect_start_time_.is_null()); | 442 DCHECK(!fallback_connect_start_time_.is_null()); |
| 443 | |
| 444 // Success will be returned via the fallback socket, so also include | |
| 445 // connection attempts made on the main socket. | |
| 446 if (transport_socket_) { | |
| 447 ConnectionAttempts attempts; | |
| 448 transport_socket_->GetConnectionAttempts(&attempts); | |
| 449 fallback_transport_socket_->AddConnectionAttempts(attempts); | |
| 450 } | |
| 451 | |
| 431 connect_timing_.connect_start = fallback_connect_start_time_; | 452 connect_timing_.connect_start = fallback_connect_start_time_; |
| 432 helper_.HistogramDuration( | 453 helper_.HistogramDuration( |
| 433 TransportConnectJobHelper::CONNECTION_LATENCY_IPV4_WINS_RACE); | 454 TransportConnectJobHelper::CONNECTION_LATENCY_IPV4_WINS_RACE); |
| 434 SetSocket(fallback_transport_socket_.Pass()); | 455 SetSocket(fallback_transport_socket_.Pass()); |
| 435 helper_.set_next_state(TransportConnectJobHelper::STATE_NONE); | 456 helper_.set_next_state(TransportConnectJobHelper::STATE_NONE); |
| 436 transport_socket_.reset(); | 457 transport_socket_.reset(); |
| 437 } else { | 458 } else { |
| 459 // Failure will be returned via |GetAdditionalErrorState|, so save | |
| 460 // connection attempts from both sockets for use there. | |
| 461 CopyConnectionAttemptsFromClientSocketHandles(); | |
| 462 | |
| 438 // Be a bit paranoid and kill off the fallback members to prevent reuse. | 463 // Be a bit paranoid and kill off the fallback members to prevent reuse. |
| 439 fallback_transport_socket_.reset(); | 464 fallback_transport_socket_.reset(); |
| 440 fallback_addresses_.reset(); | 465 fallback_addresses_.reset(); |
| 441 } | 466 } |
| 442 NotifyDelegateOfCompletion(result); // Deletes |this| | 467 NotifyDelegateOfCompletion(result); // Deletes |this| |
| 443 } | 468 } |
| 444 | 469 |
| 445 int TransportConnectJob::ConnectInternal() { | 470 int TransportConnectJob::ConnectInternal() { |
| 446 return helper_.DoConnectInternal(this); | 471 return helper_.DoConnectInternal(this); |
| 447 } | 472 } |
| 448 | 473 |
| 474 void TransportConnectJob::CopyConnectionAttemptsFromClientSocketHandles() { | |
| 475 if (transport_socket_) | |
| 476 transport_socket_->GetConnectionAttempts(&connection_attempts_); | |
| 477 if (fallback_transport_socket_) { | |
| 478 fallback_transport_socket_->GetConnectionAttempts( | |
| 479 &fallback_connection_attempts_); | |
| 480 } | |
| 481 } | |
| 482 | |
| 449 scoped_ptr<ConnectJob> | 483 scoped_ptr<ConnectJob> |
| 450 TransportClientSocketPool::TransportConnectJobFactory::NewConnectJob( | 484 TransportClientSocketPool::TransportConnectJobFactory::NewConnectJob( |
| 451 const std::string& group_name, | 485 const std::string& group_name, |
| 452 const PoolBase::Request& request, | 486 const PoolBase::Request& request, |
| 453 ConnectJob::Delegate* delegate) const { | 487 ConnectJob::Delegate* delegate) const { |
| 454 return scoped_ptr<ConnectJob>( | 488 return scoped_ptr<ConnectJob>( |
| 455 new TransportConnectJob(group_name, | 489 new TransportConnectJob(group_name, |
| 456 request.priority(), | 490 request.priority(), |
| 457 request.params(), | 491 request.params(), |
| 458 ConnectionTimeout(), | 492 ConnectionTimeout(), |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 588 HigherLayeredPool* higher_pool) { | 622 HigherLayeredPool* higher_pool) { |
| 589 base_.AddHigherLayeredPool(higher_pool); | 623 base_.AddHigherLayeredPool(higher_pool); |
| 590 } | 624 } |
| 591 | 625 |
| 592 void TransportClientSocketPool::RemoveHigherLayeredPool( | 626 void TransportClientSocketPool::RemoveHigherLayeredPool( |
| 593 HigherLayeredPool* higher_pool) { | 627 HigherLayeredPool* higher_pool) { |
| 594 base_.RemoveHigherLayeredPool(higher_pool); | 628 base_.RemoveHigherLayeredPool(higher_pool); |
| 595 } | 629 } |
| 596 | 630 |
| 597 } // namespace net | 631 } // namespace net |
| OLD | NEW |