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

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: net-internals additions 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_disabled_reasons,
569 int threshold_public_resets_post_handshake,
570 int threshold_timeouts_with_open_streams,
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_disabled_reasons_(max_disabled_reasons),
598 num_public_resets_post_handshake_(0),
599 num_timeouts_with_open_streams_(0),
600 max_public_resets_post_handshake_(0),
601 max_timeouts_with_open_streams_(0),
602 threshold_timeouts_with_open_streams_(
603 threshold_timeouts_with_open_streams),
604 threshold_public_resets_post_handshake_(
605 threshold_public_resets_post_handshake),
594 socket_receive_buffer_size_(socket_receive_buffer_size), 606 socket_receive_buffer_size_(socket_receive_buffer_size),
595 port_seed_(random_generator_->RandUint64()), 607 port_seed_(random_generator_->RandUint64()),
596 check_persisted_supports_quic_(true), 608 check_persisted_supports_quic_(true),
597 task_runner_(nullptr), 609 task_runner_(nullptr),
598 weak_factory_(this) { 610 weak_factory_(this) {
599 DCHECK(transport_security_state_); 611 DCHECK(transport_security_state_);
600 crypto_config_.set_user_agent_id(user_agent_id); 612 crypto_config_.set_user_agent_id(user_agent_id);
601 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); 613 crypto_config_.AddCanonicalSuffix(".c.youtube.com");
602 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); 614 crypto_config_.AddCanonicalSuffix(".googlevideo.com");
603 crypto_config_.AddCanonicalSuffix(".googleusercontent.com"); 615 crypto_config_.AddCanonicalSuffix(".googleusercontent.com");
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 STLDeleteElements(&(active_jobs_[server_id])); 826 STLDeleteElements(&(active_jobs_[server_id]));
815 active_jobs_.erase(server_id); 827 active_jobs_.erase(server_id);
816 job_requests_map_.erase(server_id); 828 job_requests_map_.erase(server_id);
817 } 829 }
818 830
819 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateFromSession( 831 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateFromSession(
820 QuicClientSession* session) { 832 QuicClientSession* session) {
821 return scoped_ptr<QuicHttpStream>(new QuicHttpStream(session->GetWeakPtr())); 833 return scoped_ptr<QuicHttpStream>(new QuicHttpStream(session->GetWeakPtr()));
822 } 834 }
823 835
836 QuicDisabledReason QuicStreamFactory::QuicDisabledReason(uint16 port) {
837 if (max_number_of_lossy_connections_ > 0 &&
838 number_of_lossy_connections_[port] >= max_number_of_lossy_connections_) {
839 return QUIC_DISABLED_BAD_PACKET_LOSS_RATE;
840 }
841 if (threshold_public_resets_post_handshake_ > 0 &&
842 num_public_resets_post_handshake_ >=
843 threshold_public_resets_post_handshake_) {
844 return QUIC_DISABLED_PUBLIC_RESET_POST_HANDSHAKE;
845 }
846 if (threshold_timeouts_with_open_streams_ > 0 &&
847 num_timeouts_with_open_streams_ >=
848 threshold_timeouts_with_open_streams_) {
849 return QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS;
850 }
851 return QUIC_DISABLED_NOT;
852 }
853
854 std::string QuicStreamFactory::QuicDisabledReasonString() const {
855 // TODO(ckrasic) - better solution for lossy connections?
856 uint16 port = 443;
857 if (max_number_of_lossy_connections_ > 0 &&
858 number_of_lossy_connections_.at(port) >=
859 max_number_of_lossy_connections_) {
860 return "bad packet loss rate";
861 }
862 if (threshold_public_resets_post_handshake_ > 0 &&
863 num_public_resets_post_handshake_ >=
864 threshold_public_resets_post_handshake_) {
865 return "public resets after successful handshakes";
866 }
867 if (threshold_timeouts_with_open_streams_ > 0 &&
868 num_timeouts_with_open_streams_ >=
869 threshold_timeouts_with_open_streams_) {
870 return "connection timeouts with streams open";
871 }
Ryan Hamilton 2015/07/06 18:25:41 nit: It looks like this is just duplicating the lo
Buck 2015/07/06 21:39:32 Done.
872 return "not applicable";
873 }
874
824 bool QuicStreamFactory::IsQuicDisabled(uint16 port) { 875 bool QuicStreamFactory::IsQuicDisabled(uint16 port) {
825 return max_number_of_lossy_connections_ > 0 && 876 return QuicDisabledReason(port) != QUIC_DISABLED_NOT;
826 number_of_lossy_connections_[port] >= max_number_of_lossy_connections_;
827 } 877 }
828 878
829 bool QuicStreamFactory::OnHandshakeConfirmed(QuicClientSession* session, 879 bool QuicStreamFactory::OnHandshakeConfirmed(QuicClientSession* session,
830 float packet_loss_rate) { 880 float packet_loss_rate) {
831 DCHECK(session); 881 DCHECK(session);
832 uint16 port = session->server_id().port(); 882 uint16 port = session->server_id().port();
833 if (packet_loss_rate < packet_loss_threshold_) { 883 if (packet_loss_rate < packet_loss_threshold_) {
834 number_of_lossy_connections_[port] = 0; 884 number_of_lossy_connections_[port] = 0;
835 return false; 885 return false;
836 } 886 }
(...skipping 10 matching lines...) Expand all
847 897
848 // Collect data for port 443 for packet loss events. 898 // Collect data for port 443 for packet loss events.
849 if (port == 443 && max_number_of_lossy_connections_ > 0) { 899 if (port == 443 && max_number_of_lossy_connections_ > 0) {
850 UMA_HISTOGRAM_SPARSE_SLOWLY( 900 UMA_HISTOGRAM_SPARSE_SLOWLY(
851 base::StringPrintf("Net.QuicStreamFactory.BadPacketLossEvents%d", 901 base::StringPrintf("Net.QuicStreamFactory.BadPacketLossEvents%d",
852 max_number_of_lossy_connections_), 902 max_number_of_lossy_connections_),
853 std::min(number_of_lossy_connections_[port], 903 std::min(number_of_lossy_connections_[port],
854 max_number_of_lossy_connections_)); 904 max_number_of_lossy_connections_));
855 } 905 }
856 906
857 bool is_quic_disabled = IsQuicDisabled(port); 907 enum QuicDisabledReason disabled_reason = QuicDisabledReason(port);
858 if (is_quic_disabled) { 908 if (disabled_reason == QUIC_DISABLED_NOT)
909 return false;
910
911 if (disabled_reason == QUIC_DISABLED_PUBLIC_RESET_POST_HANDSHAKE) {
859 // Close QUIC connection if Quic is disabled for this port. 912 // Close QUIC connection if Quic is disabled for this port.
860 session->CloseSessionOnErrorAndNotifyFactoryLater( 913 session->CloseSessionOnErrorAndNotifyFactoryLater(
914 ERR_ABORTED, QUIC_PUBLIC_RESETS_POST_HANDSHAKE);
915 } else if (disabled_reason == QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS) {
916 session->CloseSessionOnErrorAndNotifyFactoryLater(
917 ERR_ABORTED, QUIC_TIMEOUTS_WITH_OPEN_STREAMS);
918 } else if (!was_quic_disabled &&
919 disabled_reason == QUIC_DISABLED_BAD_PACKET_LOSS_RATE) {
920 session->CloseSessionOnErrorAndNotifyFactoryLater(
861 ERR_ABORTED, QUIC_BAD_PACKET_LOSS_RATE); 921 ERR_ABORTED, QUIC_BAD_PACKET_LOSS_RATE);
862
863 // If this bad packet loss rate disabled the QUIC, then record it. 922 // If this bad packet loss rate disabled the QUIC, then record it.
864 if (!was_quic_disabled) 923 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicStreamFactory.QuicIsDisabled", port);
865 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicStreamFactory.QuicIsDisabled", port);
866 } 924 }
867 return is_quic_disabled; 925 return true;
868 } 926 }
869 927
870 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) { 928 void QuicStreamFactory::OnIdleSession(QuicClientSession* session) {
871 } 929 }
872 930
873 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) { 931 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) {
874 const AliasSet& aliases = session_aliases_[session]; 932 const AliasSet& aliases = session_aliases_[session];
875 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); 933 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end();
876 ++it) { 934 ++it) {
877 DCHECK(active_sessions_.count(*it)); 935 DCHECK(active_sessions_.count(*it));
(...skipping 12 matching lines...) Expand all
890 const IpAliasKey ip_alias_key(session->connection()->peer_address(), 948 const IpAliasKey ip_alias_key(session->connection()->peer_address(),
891 aliases.begin()->is_https()); 949 aliases.begin()->is_https());
892 ip_aliases_[ip_alias_key].erase(session); 950 ip_aliases_[ip_alias_key].erase(session);
893 if (ip_aliases_[ip_alias_key].empty()) { 951 if (ip_aliases_[ip_alias_key].empty()) {
894 ip_aliases_.erase(ip_alias_key); 952 ip_aliases_.erase(ip_alias_key);
895 } 953 }
896 } 954 }
897 session_aliases_.erase(session); 955 session_aliases_.erase(session);
898 } 956 }
899 957
958 void QuicStreamFactory::MaybeDisableQuic(QuicClientSession* session) {
959 DCHECK(session);
960 uint16 port = session->server_id().port();
961 if (IsQuicDisabled(port))
962 return;
963
964 // Expire the oldest disabled_reason if appropriate. This enforces that we
965 // only consider the max_disabled_reasons_ most recent sessions.
966 enum QuicDisabledReason disabled_reason;
967 if (static_cast<int>(disabled_reasons_.size()) == max_disabled_reasons_) {
968 disabled_reason = disabled_reasons_.front();
969 disabled_reasons_.pop_front();
970 if (disabled_reason == QUIC_DISABLED_PUBLIC_RESET_POST_HANDSHAKE) {
971 num_public_resets_post_handshake_--;
972 } else if (disabled_reason == QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS) {
973 num_timeouts_with_open_streams_--;
974 }
975 }
976 disabled_reason = session->disabled_reason();
977 disabled_reasons_.push_back(disabled_reason);
978 if (disabled_reason == QUIC_DISABLED_PUBLIC_RESET_POST_HANDSHAKE) {
979 num_public_resets_post_handshake_++;
980 } else if (disabled_reason == QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS) {
981 num_timeouts_with_open_streams_++;
982 }
983 if (num_timeouts_with_open_streams_ > max_timeouts_with_open_streams_) {
984 max_timeouts_with_open_streams_ = num_timeouts_with_open_streams_;
985 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicStreamFactory.TimeoutsWithOpenStreams",
986 num_timeouts_with_open_streams_, 0, 20, 10);
987 }
988
989 if (num_public_resets_post_handshake_ > max_public_resets_post_handshake_) {
990 max_public_resets_post_handshake_ = num_public_resets_post_handshake_;
991 UMA_HISTOGRAM_CUSTOM_COUNTS(
992 "Net.QuicStreamFactory.PublicResetsPostHandshake",
993 num_public_resets_post_handshake_, 0, 20, 10);
994 }
995
996 if (IsQuicDisabled(port)) {
997 UMA_HISTOGRAM_ENUMERATION("Net.QuicStreamFactory.DisabledReasons",
998 disabled_reason, QUIC_DISABLED_MAX);
999 }
1000 }
1001
900 void QuicStreamFactory::OnSessionClosed(QuicClientSession* session) { 1002 void QuicStreamFactory::OnSessionClosed(QuicClientSession* session) {
901 DCHECK_EQ(0u, session->GetNumOpenStreams()); 1003 DCHECK_EQ(0u, session->GetNumOpenStreams());
1004 MaybeDisableQuic(session);
902 OnSessionGoingAway(session); 1005 OnSessionGoingAway(session);
903 delete session; 1006 delete session;
904 all_sessions_.erase(session); 1007 all_sessions_.erase(session);
905 } 1008 }
906 1009
907 void QuicStreamFactory::OnSessionConnectTimeout( 1010 void QuicStreamFactory::OnSessionConnectTimeout(
908 QuicClientSession* session) { 1011 QuicClientSession* session) {
909 const AliasSet& aliases = session_aliases_[session]; 1012 const AliasSet& aliases = session_aliases_[session];
910 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); 1013 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end();
911 ++it) { 1014 ++it) {
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 // Since the session was active, there's no longer an 1374 // Since the session was active, there's no longer an
1272 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP 1375 // 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 1376 // 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 1377 // it as recently broken, which means that 0-RTT will be disabled but we'll
1275 // still race. 1378 // still race.
1276 http_server_properties_->MarkAlternativeServiceRecentlyBroken( 1379 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
1277 alternative_service); 1380 alternative_service);
1278 } 1381 }
1279 1382
1280 } // namespace net 1383 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698