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) { |
|
Randy Smith (Not in Mondays)
2015/05/12 20:11:09
Given our conversation as to logging philosophy at
Deprecated (see juliatuttle)
2015/05/13 18:22:29
Done.
| |
| 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
I'd like to just acknowledge that we're grabbing i
Deprecated (see juliatuttle)
2015/05/13 18:22:29
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(); | |
|
Randy Smith (Not in Mondays)
2015/05/12 20:11:09
So if the main connection fails, but the fallback
Deprecated (see juliatuttle)
2015/05/13 18:22:29
If the main connection fails, this returns the fai
Randy Smith (Not in Mondays)
2015/05/14 19:42:04
If we're racing two connection attempts, why would
| |
| 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 |
| 400 // N.B.: The owner of the ConnectJob will delete it after the callback is | |
| 401 // called, so the fallback socket, if any, won't stick around for long. | |
| 402 | |
| 388 return result; | 403 return result; |
| 389 } | 404 } |
| 390 | 405 |
| 391 void TransportConnectJob::DoIPv6FallbackTransportConnect() { | 406 void TransportConnectJob::DoIPv6FallbackTransportConnect() { |
| 392 // The timer should only fire while we're waiting for the main connect to | 407 // The timer should only fire while we're waiting for the main connect to |
| 393 // succeed. | 408 // succeed. |
| 394 if (helper_.next_state() != | 409 if (helper_.next_state() != |
| 395 TransportConnectJobHelper::STATE_TRANSPORT_CONNECT_COMPLETE) { | 410 TransportConnectJobHelper::STATE_TRANSPORT_CONNECT_COMPLETE) { |
| 396 NOTREACHED(); | 411 NOTREACHED(); |
| 397 return; | 412 return; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 421 NOTREACHED(); | 436 NOTREACHED(); |
| 422 return; | 437 return; |
| 423 } | 438 } |
| 424 | 439 |
| 425 DCHECK_NE(ERR_IO_PENDING, result); | 440 DCHECK_NE(ERR_IO_PENDING, result); |
| 426 DCHECK(fallback_transport_socket_.get()); | 441 DCHECK(fallback_transport_socket_.get()); |
| 427 DCHECK(fallback_addresses_.get()); | 442 DCHECK(fallback_addresses_.get()); |
| 428 | 443 |
| 429 if (result == OK) { | 444 if (result == OK) { |
| 430 DCHECK(!fallback_connect_start_time_.is_null()); | 445 DCHECK(!fallback_connect_start_time_.is_null()); |
| 446 | |
| 447 // Success will be returned via the fallback socket, so also include | |
| 448 // connection attempts made on the main socket. | |
|
Randy Smith (Not in Mondays)
2015/05/12 20:11:09
" ... made to this point on ..."
Deprecated (see juliatuttle)
2015/05/13 18:22:29
Done.
| |
| 449 if (transport_socket_) { | |
| 450 ConnectionAttempts attempts; | |
| 451 transport_socket_->GetConnectionAttempts(&attempts); | |
| 452 fallback_transport_socket_->AddConnectionAttempts(attempts); | |
| 453 } | |
| 454 | |
| 431 connect_timing_.connect_start = fallback_connect_start_time_; | 455 connect_timing_.connect_start = fallback_connect_start_time_; |
| 432 helper_.HistogramDuration( | 456 helper_.HistogramDuration( |
| 433 TransportConnectJobHelper::CONNECTION_LATENCY_IPV4_WINS_RACE); | 457 TransportConnectJobHelper::CONNECTION_LATENCY_IPV4_WINS_RACE); |
| 434 SetSocket(fallback_transport_socket_.Pass()); | 458 SetSocket(fallback_transport_socket_.Pass()); |
| 435 helper_.set_next_state(TransportConnectJobHelper::STATE_NONE); | 459 helper_.set_next_state(TransportConnectJobHelper::STATE_NONE); |
| 436 transport_socket_.reset(); | 460 transport_socket_.reset(); |
| 437 } else { | 461 } else { |
| 462 // Failure will be returned via |GetAdditionalErrorState|, so save | |
| 463 // connection attempts from both sockets for use there. | |
| 464 CopyConnectionAttemptsFromClientSocketHandles(); | |
| 465 | |
| 438 // Be a bit paranoid and kill off the fallback members to prevent reuse. | 466 // Be a bit paranoid and kill off the fallback members to prevent reuse. |
| 439 fallback_transport_socket_.reset(); | 467 fallback_transport_socket_.reset(); |
| 440 fallback_addresses_.reset(); | 468 fallback_addresses_.reset(); |
| 441 } | 469 } |
| 470 | |
| 471 // N.B.: The owner of the ConnectJob will delete it after the callback is | |
| 472 // called, so the main socket, if any, won't stick around for long. | |
| 473 | |
| 442 NotifyDelegateOfCompletion(result); // Deletes |this| | 474 NotifyDelegateOfCompletion(result); // Deletes |this| |
| 443 } | 475 } |
| 444 | 476 |
| 445 int TransportConnectJob::ConnectInternal() { | 477 int TransportConnectJob::ConnectInternal() { |
| 446 return helper_.DoConnectInternal(this); | 478 return helper_.DoConnectInternal(this); |
| 447 } | 479 } |
| 448 | 480 |
| 481 void TransportConnectJob::CopyConnectionAttemptsFromClientSocketHandles() { | |
| 482 if (transport_socket_) | |
| 483 transport_socket_->GetConnectionAttempts(&connection_attempts_); | |
| 484 if (fallback_transport_socket_) { | |
| 485 fallback_transport_socket_->GetConnectionAttempts( | |
| 486 &fallback_connection_attempts_); | |
| 487 } | |
| 488 } | |
| 489 | |
| 449 scoped_ptr<ConnectJob> | 490 scoped_ptr<ConnectJob> |
| 450 TransportClientSocketPool::TransportConnectJobFactory::NewConnectJob( | 491 TransportClientSocketPool::TransportConnectJobFactory::NewConnectJob( |
| 451 const std::string& group_name, | 492 const std::string& group_name, |
| 452 const PoolBase::Request& request, | 493 const PoolBase::Request& request, |
| 453 ConnectJob::Delegate* delegate) const { | 494 ConnectJob::Delegate* delegate) const { |
| 454 return scoped_ptr<ConnectJob>( | 495 return scoped_ptr<ConnectJob>( |
| 455 new TransportConnectJob(group_name, | 496 new TransportConnectJob(group_name, |
| 456 request.priority(), | 497 request.priority(), |
| 457 request.params(), | 498 request.params(), |
| 458 ConnectionTimeout(), | 499 ConnectionTimeout(), |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 588 HigherLayeredPool* higher_pool) { | 629 HigherLayeredPool* higher_pool) { |
| 589 base_.AddHigherLayeredPool(higher_pool); | 630 base_.AddHigherLayeredPool(higher_pool); |
| 590 } | 631 } |
| 591 | 632 |
| 592 void TransportClientSocketPool::RemoveHigherLayeredPool( | 633 void TransportClientSocketPool::RemoveHigherLayeredPool( |
| 593 HigherLayeredPool* higher_pool) { | 634 HigherLayeredPool* higher_pool) { |
| 594 base_.RemoveHigherLayeredPool(higher_pool); | 635 base_.RemoveHigherLayeredPool(higher_pool); |
| 595 } | 636 } |
| 596 | 637 |
| 597 } // namespace net | 638 } // namespace net |
| OLD | NEW |