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/quic/quic_stream_factory.h" | 5 #include "net/quic/quic_stream_factory.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 | 425 |
426 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) { | 426 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) { |
427 } | 427 } |
428 | 428 |
429 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { | 429 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { |
430 const AliasSet& aliases = session_aliases_[session]; | 430 const AliasSet& aliases = session_aliases_[session]; |
431 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); | 431 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); |
432 ++it) { | 432 ++it) { |
433 DCHECK(active_sessions_.count(*it)); | 433 DCHECK(active_sessions_.count(*it)); |
434 DCHECK_EQ(session, active_sessions_[*it]); | 434 DCHECK_EQ(session, active_sessions_[*it]); |
| 435 // Track sessions which have recently gone away so that we can disable |
| 436 // port suggestions. |
| 437 if (session->goaway_received()) { |
| 438 gone_away_aliases_.insert(*it); |
| 439 } |
| 440 |
435 active_sessions_.erase(*it); | 441 active_sessions_.erase(*it); |
436 if (!http_server_properties_) | 442 if (!http_server_properties_) |
437 continue; | 443 continue; |
438 | 444 |
439 if (!session->IsCryptoHandshakeConfirmed()) { | 445 if (!session->IsCryptoHandshakeConfirmed()) { |
440 // TODO(rch): In the special case where the session has received no | 446 // TODO(rch): In the special case where the session has received no |
441 // packets from the peer, we should consider blacklisting this | 447 // packets from the peer, we should consider blacklisting this |
442 // differently so that we still race TCP but we don't consider the | 448 // differently so that we still race TCP but we don't consider the |
443 // session connected until the handshake has been confirmed. | 449 // session connected until the handshake has been confirmed. |
444 http_server_properties_->SetBrokenAlternateProtocol(it->first); | 450 http_server_properties_->SetBrokenAlternateProtocol(it->first); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 return ContainsKey(active_sessions_, host_port_proxy_pair); | 536 return ContainsKey(active_sessions_, host_port_proxy_pair); |
531 } | 537 } |
532 | 538 |
533 int QuicStreamFactory::CreateSession( | 539 int QuicStreamFactory::CreateSession( |
534 const HostPortProxyPair& host_port_proxy_pair, | 540 const HostPortProxyPair& host_port_proxy_pair, |
535 bool is_https, | 541 bool is_https, |
536 CertVerifier* cert_verifier, | 542 CertVerifier* cert_verifier, |
537 const AddressList& address_list, | 543 const AddressList& address_list, |
538 const BoundNetLog& net_log, | 544 const BoundNetLog& net_log, |
539 QuicClientSession** session) { | 545 QuicClientSession** session) { |
| 546 bool enable_port_selection = enable_port_selection_; |
| 547 if (enable_port_selection && |
| 548 ContainsKey(gone_away_aliases_, host_port_proxy_pair)) { |
| 549 // Disable port selection when the server is going away. |
| 550 // There is no point in trying to return to the same server, if |
| 551 // that server is no longer handling requests. |
| 552 enable_port_selection = false; |
| 553 gone_away_aliases_.erase(host_port_proxy_pair); |
| 554 } |
| 555 |
540 QuicConnectionId connection_id = random_generator_->RandUint64(); | 556 QuicConnectionId connection_id = random_generator_->RandUint64(); |
541 IPEndPoint addr = *address_list.begin(); | 557 IPEndPoint addr = *address_list.begin(); |
542 scoped_refptr<PortSuggester> port_suggester = | 558 scoped_refptr<PortSuggester> port_suggester = |
543 new PortSuggester(host_port_proxy_pair.first, port_seed_); | 559 new PortSuggester(host_port_proxy_pair.first, port_seed_); |
544 DatagramSocket::BindType bind_type = enable_port_selection_ ? | 560 DatagramSocket::BindType bind_type = enable_port_selection ? |
545 DatagramSocket::RANDOM_BIND : // Use our callback. | 561 DatagramSocket::RANDOM_BIND : // Use our callback. |
546 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. | 562 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. |
547 scoped_ptr<DatagramClientSocket> socket( | 563 scoped_ptr<DatagramClientSocket> socket( |
548 client_socket_factory_->CreateDatagramClientSocket( | 564 client_socket_factory_->CreateDatagramClientSocket( |
549 bind_type, | 565 bind_type, |
550 base::Bind(&PortSuggester::SuggestPort, port_suggester), | 566 base::Bind(&PortSuggester::SuggestPort, port_suggester), |
551 net_log.net_log(), net_log.source())); | 567 net_log.net_log(), net_log.source())); |
552 int rv = socket->Connect(addr); | 568 int rv = socket->Connect(addr); |
553 if (rv != OK) | 569 if (rv != OK) |
554 return rv; | 570 return rv; |
555 UMA_HISTOGRAM_COUNTS("Net.QuicEphemeralPortsSuggested", | 571 UMA_HISTOGRAM_COUNTS("Net.QuicEphemeralPortsSuggested", |
556 port_suggester->call_count()); | 572 port_suggester->call_count()); |
557 if (enable_port_selection_) { | 573 if (enable_port_selection) { |
558 DCHECK_LE(1u, port_suggester->call_count()); | 574 DCHECK_LE(1u, port_suggester->call_count()); |
559 } else { | 575 } else { |
560 DCHECK_EQ(0u, port_suggester->call_count()); | 576 DCHECK_EQ(0u, port_suggester->call_count()); |
561 } | 577 } |
562 | 578 |
563 // We should adaptively set this buffer size, but for now, we'll use a size | 579 // We should adaptively set this buffer size, but for now, we'll use a size |
564 // that is more than large enough for a full receive window, and yet | 580 // that is more than large enough for a full receive window, and yet |
565 // does not consume "too much" memory. If we see bursty packet loss, we may | 581 // does not consume "too much" memory. If we see bursty packet loss, we may |
566 // revisit this setting and test for its impact. | 582 // revisit this setting and test for its impact. |
567 const int32 kSocketBufferSize(TcpReceiver::kReceiveWindowTCP); | 583 const int32 kSocketBufferSize(TcpReceiver::kReceiveWindowTCP); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 // Copy the CachedState for the canonical server from canonical_crypto_config | 703 // Copy the CachedState for the canonical server from canonical_crypto_config |
688 // as the initial CachedState for the server_hostname in crypto_config. | 704 // as the initial CachedState for the server_hostname in crypto_config. |
689 crypto_config->InitializeFrom(server_hostname, | 705 crypto_config->InitializeFrom(server_hostname, |
690 canonical_host_port_proxy_pair.first.host(), | 706 canonical_host_port_proxy_pair.first.host(), |
691 canonical_crypto_config); | 707 canonical_crypto_config); |
692 // Update canonical version to point at the "most recent" crypto_config. | 708 // Update canonical version to point at the "most recent" crypto_config. |
693 canonical_hostname_to_origin_map_[canonical_host_port] = host_port_proxy_pair; | 709 canonical_hostname_to_origin_map_[canonical_host_port] = host_port_proxy_pair; |
694 } | 710 } |
695 | 711 |
696 } // namespace net | 712 } // namespace net |
OLD | NEW |