Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: net/quic/quic_stream_factory.cc

Issue 1208933004: QUIC - disable QUIC under recent pathological connection errors. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 9
10 #include "base/cpu.h" 10 #include "base/cpu.h"
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 bool enable_port_selection, 558 bool enable_port_selection,
559 bool always_require_handshake_confirmation, 559 bool always_require_handshake_confirmation,
560 bool disable_connection_pooling, 560 bool disable_connection_pooling,
561 float load_server_info_timeout_srtt_multiplier, 561 float load_server_info_timeout_srtt_multiplier,
562 bool enable_connection_racing, 562 bool enable_connection_racing,
563 bool enable_non_blocking_io, 563 bool enable_non_blocking_io,
564 bool disable_disk_cache, 564 bool disable_disk_cache,
565 bool prefer_aes, 565 bool prefer_aes,
566 int max_number_of_lossy_connections, 566 int max_number_of_lossy_connections,
567 float packet_loss_threshold, 567 float packet_loss_threshold,
568 int max_epitaphs,
569 int threshold_public_resets_post_handshake,
570 int threshold_timeouts_streams_open,
568 int socket_receive_buffer_size, 571 int socket_receive_buffer_size,
569 const QuicTagVector& connection_options) 572 const QuicTagVector& connection_options)
570 : require_confirmation_(true), 573 : require_confirmation_(true),
571 host_resolver_(host_resolver), 574 host_resolver_(host_resolver),
572 client_socket_factory_(client_socket_factory), 575 client_socket_factory_(client_socket_factory),
573 http_server_properties_(http_server_properties), 576 http_server_properties_(http_server_properties),
574 transport_security_state_(transport_security_state), 577 transport_security_state_(transport_security_state),
575 quic_server_info_factory_(nullptr), 578 quic_server_info_factory_(nullptr),
576 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory), 579 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory),
577 random_generator_(random_generator), 580 random_generator_(random_generator),
578 clock_(clock), 581 clock_(clock),
579 max_packet_length_(max_packet_length), 582 max_packet_length_(max_packet_length),
580 config_(InitializeQuicConfig(connection_options)), 583 config_(InitializeQuicConfig(connection_options)),
581 supported_versions_(supported_versions), 584 supported_versions_(supported_versions),
582 enable_port_selection_(enable_port_selection), 585 enable_port_selection_(enable_port_selection),
583 always_require_handshake_confirmation_( 586 always_require_handshake_confirmation_(
584 always_require_handshake_confirmation), 587 always_require_handshake_confirmation),
585 disable_connection_pooling_(disable_connection_pooling), 588 disable_connection_pooling_(disable_connection_pooling),
586 load_server_info_timeout_srtt_multiplier_( 589 load_server_info_timeout_srtt_multiplier_(
587 load_server_info_timeout_srtt_multiplier), 590 load_server_info_timeout_srtt_multiplier),
588 enable_connection_racing_(enable_connection_racing), 591 enable_connection_racing_(enable_connection_racing),
589 enable_non_blocking_io_(enable_non_blocking_io), 592 enable_non_blocking_io_(enable_non_blocking_io),
590 disable_disk_cache_(disable_disk_cache), 593 disable_disk_cache_(disable_disk_cache),
591 prefer_aes_(prefer_aes), 594 prefer_aes_(prefer_aes),
592 max_number_of_lossy_connections_(max_number_of_lossy_connections), 595 max_number_of_lossy_connections_(max_number_of_lossy_connections),
593 packet_loss_threshold_(packet_loss_threshold), 596 packet_loss_threshold_(packet_loss_threshold),
597 max_epitaphs_(max_epitaphs),
598 public_resets_post_handshake_(0),
599 timeouts_streams_open_(0),
600 max_public_resets_post_handshake_(0),
601 max_timeouts_streams_open_(0),
602 threshold_timeouts_streams_open_(threshold_timeouts_streams_open),
603 threshold_public_resets_post_handshake_(
604 threshold_public_resets_post_handshake),
594 socket_receive_buffer_size_(socket_receive_buffer_size), 605 socket_receive_buffer_size_(socket_receive_buffer_size),
595 port_seed_(random_generator_->RandUint64()), 606 port_seed_(random_generator_->RandUint64()),
596 check_persisted_supports_quic_(true), 607 check_persisted_supports_quic_(true),
597 task_runner_(nullptr), 608 task_runner_(nullptr),
598 weak_factory_(this) { 609 weak_factory_(this) {
599 DCHECK(transport_security_state_); 610 DCHECK(transport_security_state_);
600 crypto_config_.set_user_agent_id(user_agent_id); 611 crypto_config_.set_user_agent_id(user_agent_id);
601 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); 612 crypto_config_.AddCanonicalSuffix(".c.youtube.com");
602 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); 613 crypto_config_.AddCanonicalSuffix(".googlevideo.com");
603 crypto_config_.AddCanonicalSuffix(".googleusercontent.com"); 614 crypto_config_.AddCanonicalSuffix(".googleusercontent.com");
604 crypto_config_.SetProofVerifier( 615 crypto_config_.SetProofVerifier(
605 new ProofVerifierChromium(cert_verifier, transport_security_state)); 616 new ProofVerifierChromium(cert_verifier, transport_security_state));
606 // TODO(rtenneti): http://crbug.com/487355. Temporary fix for b/20760730 until 617 // TODO(rtenneti): http://crbug.com/487355. Temporary fix for b/20760730 until
607 // channel_id_service is supported in cronet. 618 // channel_id_service is supported in cronet.
608 if (channel_id_service) { 619 if (channel_id_service) {
609 crypto_config_.SetChannelIDSource( 620 crypto_config_.SetChannelIDSource(
610 new ChannelIDSourceChromium(channel_id_service)); 621 new ChannelIDSourceChromium(channel_id_service));
611 } 622 }
612 base::CPU cpu; 623 base::CPU cpu;
613 bool has_aes_hardware_support = cpu.has_aesni() && cpu.has_avx(); 624 bool has_aes_hardware_support = cpu.has_aesni() && cpu.has_avx();
614 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.PreferAesGcm", 625 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.PreferAesGcm",
615 has_aes_hardware_support); 626 has_aes_hardware_support);
616 if (has_aes_hardware_support || prefer_aes_) 627 if (has_aes_hardware_support || prefer_aes_)
617 crypto_config_.PreferAesGcm(); 628 crypto_config_.PreferAesGcm();
618 if (!IsEcdsaSupported()) 629 if (!IsEcdsaSupported())
619 crypto_config_.DisableEcdsa(); 630 crypto_config_.DisableEcdsa();
620 } 631 }
621 632
622 QuicStreamFactory::~QuicStreamFactory() { 633 QuicStreamFactory::~QuicStreamFactory() {
634 // TODO: need a separate max to track this.
Ryan Hamilton 2015/06/30 18:55:32 TODO:(ckrasic) since you have the context?
Buck 2015/07/01 19:06:19 Removed, the comment was obsolete.
635 if (max_public_resets_post_handshake_ > 0) {
636 UMA_HISTOGRAM_CUSTOM_COUNTS(
637 "Net.QuicStreamFactory.PublicResetsPostHandshake",
638 public_resets_post_handshake_, 0, max_epitaphs_, max_epitaphs_ / 2);
639 }
640 if (max_timeouts_streams_open_ > 0) {
641 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicStreamFactory.TimeoutsStreamsOpen",
642 public_resets_post_handshake_, 0, max_epitaphs_,
643 max_epitaphs_ / 2);
644 }
Ryan Hamilton 2015/06/30 18:55:32 I think this is too late for histograms to be of m
Buck 2015/07/01 19:06:19 Ok. I've moved these to where max_* get increment
623 CloseAllSessions(ERR_ABORTED); 645 CloseAllSessions(ERR_ABORTED);
624 while (!all_sessions_.empty()) { 646 while (!all_sessions_.empty()) {
625 delete all_sessions_.begin()->first; 647 delete all_sessions_.begin()->first;
626 all_sessions_.erase(all_sessions_.begin()); 648 all_sessions_.erase(all_sessions_.begin());
627 } 649 }
628 while (!active_jobs_.empty()) { 650 while (!active_jobs_.empty()) {
629 const QuicServerId server_id = active_jobs_.begin()->first; 651 const QuicServerId server_id = active_jobs_.begin()->first;
630 STLDeleteElements(&(active_jobs_[server_id])); 652 STLDeleteElements(&(active_jobs_[server_id]));
631 active_jobs_.erase(server_id); 653 active_jobs_.erase(server_id);
632 } 654 }
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 STLDeleteElements(&(active_jobs_[server_id])); 836 STLDeleteElements(&(active_jobs_[server_id]));
815 active_jobs_.erase(server_id); 837 active_jobs_.erase(server_id);
816 job_requests_map_.erase(server_id); 838 job_requests_map_.erase(server_id);
817 } 839 }
818 840
819 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateFromSession( 841 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateFromSession(
820 QuicClientSession* session) { 842 QuicClientSession* session) {
821 return scoped_ptr<QuicHttpStream>(new QuicHttpStream(session->GetWeakPtr())); 843 return scoped_ptr<QuicHttpStream>(new QuicHttpStream(session->GetWeakPtr()));
822 } 844 }
823 845
846 QuicErrorCode QuicStreamFactory::QuicDisabledReason(uint16 port) {
847 if (max_number_of_lossy_connections_ > 0 &&
848 number_of_lossy_connections_[port] >= max_number_of_lossy_connections_) {
849 return QUIC_BAD_PACKET_LOSS_RATE;
850 }
851 if (threshold_public_resets_post_handshake_ > 0 &&
852 public_resets_post_handshake_ >=
853 threshold_public_resets_post_handshake_) {
854 return QUIC_PUBLIC_RESETS_POST_HANDSHAKE;
855 }
856 if (threshold_timeouts_streams_open_ > 0 &&
857 timeouts_streams_open_ >= threshold_timeouts_streams_open_) {
858 return QUIC_TIMEOUTS_STREAMS_OPEN;
859 }
860 return QUIC_NO_ERROR;
861 }
862
824 bool QuicStreamFactory::IsQuicDisabled(uint16 port) { 863 bool QuicStreamFactory::IsQuicDisabled(uint16 port) {
825 return max_number_of_lossy_connections_ > 0 && 864 return (QuicDisabledReason(port) != QUIC_NO_ERROR);
Ryan Hamilton 2015/06/30 18:55:32 nit: no need for the extra ()s
Buck 2015/07/01 19:06:19 Done.
826 number_of_lossy_connections_[port] >= max_number_of_lossy_connections_;
827 } 865 }
828 866
829 bool QuicStreamFactory::OnHandshakeConfirmed(QuicClientSession* session, 867 bool QuicStreamFactory::OnHandshakeConfirmed(QuicClientSession* session,
830 float packet_loss_rate) { 868 float packet_loss_rate) {
831 DCHECK(session); 869 DCHECK(session);
832 uint16 port = session->server_id().port(); 870 uint16 port = session->server_id().port();
833 if (packet_loss_rate < packet_loss_threshold_) { 871 if (packet_loss_rate < packet_loss_threshold_) {
834 number_of_lossy_connections_[port] = 0; 872 number_of_lossy_connections_[port] = 0;
835 return false; 873 return false;
836 } 874 }
(...skipping 10 matching lines...) Expand all
847 885
848 // Collect data for port 443 for packet loss events. 886 // Collect data for port 443 for packet loss events.
849 if (port == 443 && max_number_of_lossy_connections_ > 0) { 887 if (port == 443 && max_number_of_lossy_connections_ > 0) {
850 UMA_HISTOGRAM_SPARSE_SLOWLY( 888 UMA_HISTOGRAM_SPARSE_SLOWLY(
851 base::StringPrintf("Net.QuicStreamFactory.BadPacketLossEvents%d", 889 base::StringPrintf("Net.QuicStreamFactory.BadPacketLossEvents%d",
852 max_number_of_lossy_connections_), 890 max_number_of_lossy_connections_),
853 std::min(number_of_lossy_connections_[port], 891 std::min(number_of_lossy_connections_[port],
854 max_number_of_lossy_connections_)); 892 max_number_of_lossy_connections_));
855 } 893 }
856 894
857 bool is_quic_disabled = IsQuicDisabled(port); 895 QuicErrorCode error_code = QuicDisabledReason(port);
858 if (is_quic_disabled) { 896 if (error_code != QUIC_NO_ERROR) {
859 // Close QUIC connection if Quic is disabled for this port. 897 // Close QUIC connection if Quic is disabled for this port.
860 session->CloseSessionOnErrorAndNotifyFactoryLater( 898 session->CloseSessionOnErrorAndNotifyFactoryLater(ERR_ABORTED, error_code);
861 ERR_ABORTED, QUIC_BAD_PACKET_LOSS_RATE);
862 899
863 // If this bad packet loss rate disabled the QUIC, then record it. 900 // If this bad packet loss rate disabled the QUIC, then record it.
864 if (!was_quic_disabled) 901 if (!was_quic_disabled && error_code == QUIC_BAD_PACKET_LOSS_RATE)
865 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicStreamFactory.QuicIsDisabled", port); 902 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicStreamFactory.QuicIsDisabled", port);
903 return true;
866 } 904 }
867 return is_quic_disabled; 905 return false;
Ryan Hamilton 2015/06/30 18:55:32 Your call, but I might write this as: if (error_c
Buck 2015/07/01 19:06:19 Done.
868 } 906 }
869 907
870 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) { 908 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) {
871 } 909 }
872 910
873 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { 911 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) {
874 const AliasSet& aliases = session_aliases_[session]; 912 const AliasSet& aliases = session_aliases_[session];
875 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); 913 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end();
876 ++it) { 914 ++it) {
877 DCHECK(active_sessions_.count(*it)); 915 DCHECK(active_sessions_.count(*it));
(...skipping 12 matching lines...) Expand all
890 const IpAliasKey ip_alias_key(session->connection()->peer_address(), 928 const IpAliasKey ip_alias_key(session->connection()->peer_address(),
891 aliases.begin()->is_https()); 929 aliases.begin()->is_https());
892 ip_aliases_[ip_alias_key].erase(session); 930 ip_aliases_[ip_alias_key].erase(session);
893 if (ip_aliases_[ip_alias_key].empty()) { 931 if (ip_aliases_[ip_alias_key].empty()) {
894 ip_aliases_.erase(ip_alias_key); 932 ip_aliases_.erase(ip_alias_key);
895 } 933 }
896 } 934 }
897 session_aliases_.erase(session); 935 session_aliases_.erase(session);
898 } 936 }
899 937
938 void QuicStreamFactory::MaybeDisableQuic(QuicClientSession* session) {
939 DCHECK(session);
940 uint16 port = session->server_id().port();
941 if (IsQuicDisabled(port))
942 return;
943
944 // Expire the oldest epitaph if appropriate. This enforces that we
945 // only consider the max_epitaphs_ most recent sessions.
946 QuicClientSessionEpitaph epitaph;
947 if ((int)epitaphs_.size() == max_epitaphs_) {
Ryan Hamilton 2015/06/30 18:55:32 nit: static_cast
Buck 2015/07/01 19:06:19 Done.
948 epitaph = epitaphs_.front();
949 epitaphs_.pop_front();
950 if (epitaph == QUIC_EPITAPH_PUBLIC_RESET_POST_HANDSHAKE) {
951 public_resets_post_handshake_--;
952 } else if (epitaph == QUIC_EPITAPH_TIMEOUT_STREAMS_OPEN) {
953 timeouts_streams_open_--;
954 }
955 }
956 epitaph = session->epitaph();
957 epitaphs_.push_back(epitaph);
958 if (epitaph == QUIC_EPITAPH_PUBLIC_RESET_POST_HANDSHAKE) {
959 public_resets_post_handshake_++;
960 } else if (epitaph == QUIC_EPITAPH_TIMEOUT_STREAMS_OPEN) {
961 timeouts_streams_open_++;
962 }
963 max_timeouts_streams_open_ =
964 std::max(timeouts_streams_open_, max_timeouts_streams_open_);
965 max_public_resets_post_handshake_ = std::max(
966 public_resets_post_handshake_, max_public_resets_post_handshake_);
Ryan Hamilton 2015/06/30 18:55:31 I'm not following the logic of resetting max_ here
Buck 2015/07/01 19:06:19 I changed this so it is hopefully more direct and
Ryan Hamilton 2015/07/06 18:25:41 Oh, I see. I was confusing max_disabled_reasons_ w
967 if (IsQuicDisabled(port)) {
968 UMA_HISTOGRAM_ENUMERATION("Net.QuicStreamFactory.DisabledReasons", epitaph,
969 QUIC_EPITAPH_MAX);
970 }
971 }
972
900 void QuicStreamFactory::OnSessionClosed(QuicClientSession* session) { 973 void QuicStreamFactory::OnSessionClosed(QuicClientSession* session) {
901 DCHECK_EQ(0u, session->GetNumOpenStreams()); 974 DCHECK_EQ(0u, session->GetNumOpenStreams());
975 MaybeDisableQuic(session);
902 OnSessionGoingAway(session); 976 OnSessionGoingAway(session);
903 delete session; 977 delete session;
904 all_sessions_.erase(session); 978 all_sessions_.erase(session);
905 } 979 }
906 980
907 void QuicStreamFactory::OnSessionConnectTimeout( 981 void QuicStreamFactory::OnSessionConnectTimeout(
908 QuicClientSession* session) { 982 QuicClientSession* session) {
909 const AliasSet& aliases = session_aliases_[session]; 983 const AliasSet& aliases = session_aliases_[session];
910 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); 984 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end();
911 ++it) { 985 ++it) {
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 // Since the session was active, there's no longer an 1345 // Since the session was active, there's no longer an
1272 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP 1346 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP
1273 // job also fails. So to avoid not using QUIC when we otherwise could, we mark 1347 // job also fails. So to avoid not using QUIC when we otherwise could, we mark
1274 // it as recently broken, which means that 0-RTT will be disabled but we'll 1348 // it as recently broken, which means that 0-RTT will be disabled but we'll
1275 // still race. 1349 // still race.
1276 http_server_properties_->MarkAlternativeServiceRecentlyBroken( 1350 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
1277 alternative_service); 1351 alternative_service);
1278 } 1352 }
1279 1353
1280 } // namespace net 1354 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698