diff options
50 files changed, 392 insertions, 223 deletions
diff --git a/net/quic/congestion_control/cubic.cc b/net/quic/congestion_control/cubic.cc index dec529d..22b0a90 100644 --- a/net/quic/congestion_control/cubic.cc +++ b/net/quic/congestion_control/cubic.cc @@ -82,8 +82,8 @@ void Cubic::UpdateCongestionControlStats( QuicTcpCongestionWindow new_cubic_mode_cwnd, QuicTcpCongestionWindow new_reno_mode_cwnd) { - QuicTcpCongestionWindow highest_new_cwnd = std::max(new_cubic_mode_cwnd, - new_reno_mode_cwnd); + QuicTcpCongestionWindow highest_new_cwnd = max(new_cubic_mode_cwnd, + new_reno_mode_cwnd); if (last_congestion_window_ < highest_new_cwnd) { // cwnd will increase to highest_new_cwnd. stats_->cwnd_increase_congestion_avoidance += diff --git a/net/quic/congestion_control/pacing_sender.cc b/net/quic/congestion_control/pacing_sender.cc index 20d2b3b..03e5534 100644 --- a/net/quic/congestion_control/pacing_sender.cc +++ b/net/quic/congestion_control/pacing_sender.cc @@ -15,15 +15,12 @@ PacingSender::PacingSender(SendAlgorithmInterface* sender, burst_tokens_(initial_packet_burst), last_delayed_packet_sent_time_(QuicTime::Zero()), next_packet_send_time_(QuicTime::Zero()), - was_last_send_delayed_(false), - has_valid_rtt_(false) { + was_last_send_delayed_(false) { } PacingSender::~PacingSender() {} void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) { - // TODO(ianswett): Consider using the suggested RTT for pacing an initial - // response. sender_->SetFromConfig(config, is_server); } @@ -42,9 +39,6 @@ void PacingSender::OnCongestionEvent(bool rtt_updated, QuicByteCount bytes_in_flight, const CongestionVector& acked_packets, const CongestionVector& lost_packets) { - if (rtt_updated) { - has_valid_rtt_ = true; - } sender_->OnCongestionEvent( rtt_updated, bytes_in_flight, acked_packets, lost_packets); } @@ -55,11 +49,10 @@ bool PacingSender::OnPacketSent( QuicPacketSequenceNumber sequence_number, QuicByteCount bytes, HasRetransmittableData has_retransmittable_data) { - // Only pace data packets once we have an updated RTT. const bool in_flight = sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number, bytes, has_retransmittable_data); - if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA || !has_valid_rtt_) { + if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA) { return in_flight; } if (burst_tokens_ > 0) { @@ -117,10 +110,6 @@ QuicTime::Delta PacingSender::TimeUntilSend( HasRetransmittableData has_retransmittable_data) const { QuicTime::Delta time_until_send = sender_->TimeUntilSend(now, bytes_in_flight, has_retransmittable_data); - if (!has_valid_rtt_) { - // Don't pace if we don't have an updated RTT estimate. - return time_until_send; - } if (bytes_in_flight == 0) { // Add more burst tokens anytime the connection is entering quiescence. burst_tokens_ = initial_packet_burst_; @@ -143,6 +132,8 @@ QuicTime::Delta PacingSender::TimeUntilSend( } // If the next send time is within the alarm granularity, send immediately. + // TODO(ianswett): This granularity logic ends up sending more packets than + // intended in an effort to make up for lost time that wasn't lost. if (next_packet_send_time_ > now.Add(alarm_granularity_)) { DVLOG(1) << "Delaying packet: " << next_packet_send_time_.Subtract(now).ToMicroseconds(); diff --git a/net/quic/congestion_control/pacing_sender.h b/net/quic/congestion_control/pacing_sender.h index 85e288e..e50527d 100644 --- a/net/quic/congestion_control/pacing_sender.h +++ b/net/quic/congestion_control/pacing_sender.h @@ -73,7 +73,6 @@ class NET_EXPORT_PRIVATE PacingSender : public SendAlgorithmInterface { QuicTime last_delayed_packet_sent_time_; QuicTime next_packet_send_time_; // When can the next packet be sent. mutable bool was_last_send_delayed_; // True when the last send was delayed. - bool has_valid_rtt_; // True if we have at least one RTT update. DISALLOW_COPY_AND_ASSIGN(PacingSender); }; diff --git a/net/quic/congestion_control/pacing_sender_test.cc b/net/quic/congestion_control/pacing_sender_test.cc index 768cc22..f887c54 100644 --- a/net/quic/congestion_control/pacing_sender_test.cc +++ b/net/quic/congestion_control/pacing_sender_test.cc @@ -19,6 +19,7 @@ namespace net { namespace test { const QuicByteCount kBytesInFlight = 1024; +const int kInitialBurstPackets = 10; class PacingSenderTest : public ::testing::Test { protected: @@ -142,11 +143,6 @@ TEST_F(PacingSenderTest, VariousSending) { .WillRepeatedly(Return(QuicBandwidth::FromBytesAndTimeDelta( kMaxPacketSize, QuicTime::Delta::FromMilliseconds(2)))); - // Send a whole pile of packets, and verify that they are not paced. - for (int i = 0 ; i < 1000; ++i) { - CheckPacketIsSentImmediately(); - } - // Now update the RTT and verify that packets are actually paced. EXPECT_CALL(*mock_sender_, OnCongestionEvent(true, kBytesInFlight, _, _)); SendAlgorithmInterface::CongestionVector empty_map; @@ -217,11 +213,6 @@ TEST_F(PacingSenderTest, CongestionAvoidanceSending) { .WillRepeatedly(Return(QuicBandwidth::FromBytesAndTimeDelta( kMaxPacketSize, QuicTime::Delta::FromMilliseconds(2)))); - // Send a whole pile of packets, and verify that they are not paced. - for (int i = 0 ; i < 1000; ++i) { - CheckPacketIsSentImmediately(); - } - // Now update the RTT and verify that packets are actually paced. EXPECT_CALL(*mock_sender_, OnCongestionEvent(true, kBytesInFlight, _, _)); SendAlgorithmInterface::CongestionVector empty_map; @@ -296,17 +287,71 @@ TEST_F(PacingSenderTest, InitialBurst) { pacing_sender_->OnCongestionEvent(true, kBytesInFlight, empty_map, empty_map); // Send 10 packets, and verify that they are not paced. - for (int i = 0 ; i < 10; ++i) { + for (int i = 0 ; i < kInitialBurstPackets; ++i) { CheckPacketIsSentImmediately(); } + // The first packet was a "make up", then we sent two packets "into the + // future", so the delay should be 2ms. CheckPacketIsSentImmediately(); CheckPacketIsSentImmediately(); CheckPacketIsSentImmediately(); + CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); + + clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5)); + CheckPacketIsSentImmediately(); + + // Next time TimeUntilSend is called with no bytes in flight, the tokens + // should be refilled and there should be no delay. + EXPECT_CALL(*mock_sender_, + TimeUntilSend(clock_.Now(), + 0, + HAS_RETRANSMITTABLE_DATA)). + WillOnce(Return(zero_time_)); + EXPECT_EQ(zero_time_, + pacing_sender_->TimeUntilSend(clock_.Now(), + 0, + HAS_RETRANSMITTABLE_DATA)); + for (int i = 0 ; i < kInitialBurstPackets; ++i) { + CheckPacketIsSentImmediately(); + } // The first packet was a "make up", then we sent two packets "into the - // future", so the delay should be 2. + // future", so the delay should be 2ms. + CheckPacketIsSentImmediately(); + CheckPacketIsSentImmediately(); + CheckPacketIsSentImmediately(); CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); +} + +TEST_F(PacingSenderTest, InitialBurstNoRttMeasurement) { + pacing_sender_.reset(); + mock_sender_ = new StrictMock<MockSendAlgorithm>(); + pacing_sender_.reset(new PacingSender(mock_sender_, + QuicTime::Delta::FromMilliseconds(1), + 10)); + // Start the test in slow start. + EXPECT_CALL(*mock_sender_, InSlowStart()).WillRepeatedly(Return(true)); + + // Configure bandwith of 1 packet per 2 ms, for which the pacing rate + // will be 1 packet per 1 ms. + EXPECT_CALL(*mock_sender_, BandwidthEstimate()) + .WillRepeatedly(Return(QuicBandwidth::FromBytesAndTimeDelta( + kMaxPacketSize, QuicTime::Delta::FromMilliseconds(2)))); + + // Send 10 packets, and verify that they are not paced. + for (int i = 0 ; i < kInitialBurstPackets; ++i) { + CheckPacketIsSentImmediately(); + } + + // The first packet was a "make up", then we sent two packets "into the + // future", so the delay should be 2ms. + CheckPacketIsSentImmediately(); + CheckPacketIsSentImmediately(); + CheckPacketIsSentImmediately(); + CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); + + clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5)); CheckPacketIsSentImmediately(); @@ -321,14 +366,16 @@ TEST_F(PacingSenderTest, InitialBurst) { pacing_sender_->TimeUntilSend(clock_.Now(), 0, HAS_RETRANSMITTABLE_DATA)); - for (int i = 0 ; i < 10; ++i) { + // Send 10 packets, and verify that they are not paced. + for (int i = 0 ; i < kInitialBurstPackets; ++i) { CheckPacketIsSentImmediately(); } + // The first packet was a "make up", then we sent two packets "into the + // future", so the delay should be 2ms. CheckPacketIsSentImmediately(); CheckPacketIsSentImmediately(); CheckPacketIsSentImmediately(); - CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); } diff --git a/net/quic/congestion_control/tcp_cubic_sender_test.cc b/net/quic/congestion_control/tcp_cubic_sender_test.cc index 851c1a1..731b8f5 100644 --- a/net/quic/congestion_control/tcp_cubic_sender_test.cc +++ b/net/quic/congestion_control/tcp_cubic_sender_test.cc @@ -670,8 +670,8 @@ TEST_F(TcpCubicSenderTest, 1ConnectionCongestionAvoidanceAtEndOfRecovery) { expected_send_window /= 2; EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow()); - // No congestion window growth should occur in recovery phase, i.e., - // until the currently outstanding 20 packets are acked. + // No congestion window growth should occur in recovery phase, i.e., until the + // currently outstanding 20 packets are acked. for (int i = 0; i < 10; ++i) { // Send our full send window. SendAvailableSendWindow(); diff --git a/net/quic/congestion_control/tcp_loss_algorithm.cc b/net/quic/congestion_control/tcp_loss_algorithm.cc index 557681e..b0a5a15 100644 --- a/net/quic/congestion_control/tcp_loss_algorithm.cc +++ b/net/quic/congestion_control/tcp_loss_algorithm.cc @@ -46,7 +46,9 @@ SequenceNumberSet TCPLossAlgorithm::DetectLostPackets( } LOG_IF(DFATAL, it->nack_count == 0) - << "All packets less than largest observed should have been nacked."; + << "All packets less than largest observed should have been nacked." + << "sequence_number:" << sequence_number + << " largest_observed:" << largest_observed; if (it->nack_count >= kNumberOfNacksBeforeRetransmission) { lost_packets.insert(sequence_number); continue; diff --git a/net/quic/crypto/quic_crypto_client_config.cc b/net/quic/crypto/quic_crypto_client_config.cc index 90dc265..1f668af 100644 --- a/net/quic/crypto/quic_crypto_client_config.cc +++ b/net/quic/crypto/quic_crypto_client_config.cc @@ -56,7 +56,9 @@ void RecordServerConfigState(ServerConfigState server_config_state) { } // namespace QuicCryptoClientConfig::QuicCryptoClientConfig() - : disable_ecdsa_(false) {} + : disable_ecdsa_(false) { + SetDefaults(); +} QuicCryptoClientConfig::~QuicCryptoClientConfig() { STLDeleteValues(&cached_states_); diff --git a/net/quic/crypto/quic_crypto_client_config.h b/net/quic/crypto/quic_crypto_client_config.h index 39c2508..9fc8ff0 100644 --- a/net/quic/crypto/quic_crypto_client_config.h +++ b/net/quic/crypto/quic_crypto_client_config.h @@ -133,9 +133,6 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { QuicCryptoClientConfig(); ~QuicCryptoClientConfig(); - // Sets the members to reasonable, default values. - void SetDefaults(); - // LookupOrCreate returns a CachedState for the given |server_id|. If no such // CachedState currently exists, it will be created and cached. CachedState* LookupOrCreate(const QuicServerId& server_id); @@ -269,6 +266,9 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { private: typedef std::map<QuicServerId, CachedState*> CachedStateMap; + // Sets the members to reasonable, default values. + void SetDefaults(); + // CacheNewServerConfig checks for SCFG, STK, PROF, and CRT tags in |message|, // verifies them, and stores them in the cached state if they validate. // This is used on receipt of a REJ from a server, or when a server sends diff --git a/net/quic/crypto/quic_crypto_client_config_test.cc b/net/quic/crypto/quic_crypto_client_config_test.cc index 31eb5fa..d2c4920 100644 --- a/net/quic/crypto/quic_crypto_client_config_test.cc +++ b/net/quic/crypto/quic_crypto_client_config_test.cc @@ -81,7 +81,6 @@ TEST(QuicCryptoClientConfigTest, InchoateChlo) { TEST(QuicCryptoClientConfigTest, PreferAesGcm) { QuicCryptoClientConfig config; - config.SetDefaults(); if (config.aead.size() > 1) EXPECT_NE(kAESG, config.aead[0]); config.PreferAesGcm(); diff --git a/net/quic/crypto/quic_crypto_server_config.cc b/net/quic/crypto/quic_crypto_server_config.cc index 29670cd..8120ae5 100644 --- a/net/quic/crypto/quic_crypto_server_config.cc +++ b/net/quic/crypto/quic_crypto_server_config.cc @@ -18,6 +18,7 @@ #include "net/quic/crypto/chacha20_poly1305_encrypter.h" #include "net/quic/crypto/channel_id.h" #include "net/quic/crypto/crypto_framer.h" +#include "net/quic/crypto/crypto_handshake_message.h" #include "net/quic/crypto/crypto_server_config_protobuf.h" #include "net/quic/crypto/crypto_utils.h" #include "net/quic/crypto/curve25519_key_exchange.h" @@ -61,49 +62,6 @@ string DeriveSourceAddressTokenKey(StringPiece source_address_token_secret) { } // namespace -// ClientHelloInfo contains information about a client hello message that is -// only kept for as long as it's being processed. -struct ClientHelloInfo { - ClientHelloInfo(const IPEndPoint& in_client_ip, QuicWallTime in_now) - : client_ip(in_client_ip), - now(in_now), - valid_source_address_token(false), - client_nonce_well_formed(false), - unique(false) {} - - // Inputs to EvaluateClientHello. - const IPEndPoint client_ip; - const QuicWallTime now; - - // Outputs from EvaluateClientHello. - bool valid_source_address_token; - bool client_nonce_well_formed; - bool unique; - StringPiece sni; - StringPiece client_nonce; - StringPiece server_nonce; - StringPiece user_agent_id; - - // Errors from EvaluateClientHello. - vector<uint32> reject_reasons; - COMPILE_ASSERT(sizeof(QuicTag) == sizeof(uint32), header_out_of_sync); -}; - -struct ValidateClientHelloResultCallback::Result { - Result(const CryptoHandshakeMessage& in_client_hello, - IPEndPoint in_client_ip, - QuicWallTime in_now) - : client_hello(in_client_hello), - info(in_client_ip, in_now), - error_code(QUIC_NO_ERROR) { - } - - CryptoHandshakeMessage client_hello; - ClientHelloInfo info; - QuicErrorCode error_code; - string error_details; -}; - class ValidateClientHelloHelper { public: ValidateClientHelloHelper(ValidateClientHelloResultCallback::Result* result, @@ -199,12 +157,36 @@ class VerifyNonceIsValidAndUniqueCallback // static const char QuicCryptoServerConfig::TESTING[] = "secret string for testing"; +ClientHelloInfo::ClientHelloInfo(const IPEndPoint& in_client_ip, + QuicWallTime in_now) + : client_ip(in_client_ip), + now(in_now), + valid_source_address_token(false), + client_nonce_well_formed(false), + unique(false) { +} + +ClientHelloInfo::~ClientHelloInfo() { +} + PrimaryConfigChangedCallback::PrimaryConfigChangedCallback() { } PrimaryConfigChangedCallback::~PrimaryConfigChangedCallback() { } +ValidateClientHelloResultCallback::Result::Result( + const CryptoHandshakeMessage& in_client_hello, + IPEndPoint in_client_ip, + QuicWallTime in_now) + : client_hello(in_client_hello), + info(in_client_ip, in_now), + error_code(QUIC_NO_ERROR) { +} + +ValidateClientHelloResultCallback::Result::~Result() { +} + ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() { } @@ -603,8 +585,9 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( !info.client_nonce_well_formed || !info.unique || !requested_config.get()) { - BuildRejection( - *primary_config.get(), client_hello, info, rand, params, out); + BuildRejection(*primary_config.get(), client_hello, info, + validate_chlo_result.cached_network_params, rand, params, + out); return QUIC_NO_ERROR; } @@ -949,8 +932,12 @@ void QuicCryptoServerConfig::EvaluateClientHello( HandshakeFailureReason source_address_token_error; StringPiece srct; if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) { - source_address_token_error = ValidateSourceAddressToken( - *requested_config.get(), srct, info->client_ip, info->now); + source_address_token_error = + ValidateSourceAddressToken(*requested_config.get(), + srct, + info->client_ip, + info->now, + &client_hello_state->cached_network_params); info->valid_source_address_token = (source_address_token_error == HANDSHAKE_OK); } else { @@ -1083,6 +1070,7 @@ void QuicCryptoServerConfig::BuildRejection( const Config& config, const CryptoHandshakeMessage& client_hello, const ClientHelloInfo& info, + const CachedNetworkParameters& cached_network_params, QuicRandom* rand, QuicCryptoNegotiatedParameters *params, CryptoHandshakeMessage* out) const { @@ -1094,7 +1082,7 @@ void QuicCryptoServerConfig::BuildRejection( info.client_ip, rand, info.now, - nullptr)); + &cached_network_params)); if (replay_protection_) { out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); } @@ -1437,7 +1425,8 @@ HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken( const Config& config, StringPiece token, const IPEndPoint& ip, - QuicWallTime now) const { + QuicWallTime now, + CachedNetworkParameters* cached_network_params) const { string storage; StringPiece plaintext; if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { @@ -1473,6 +1462,11 @@ HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken( return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE; } + if (FLAGS_quic_store_cached_network_params_from_chlo && + source_address_token.has_cached_network_parameters()) { + *cached_network_params = source_address_token.cached_network_parameters(); + } + return HANDSHAKE_OK; } diff --git a/net/quic/crypto/quic_crypto_server_config.h b/net/quic/crypto/quic_crypto_server_config.h index ef8f6e968..30e0f6d 100644 --- a/net/quic/crypto/quic_crypto_server_config.h +++ b/net/quic/crypto/quic_crypto_server_config.h @@ -36,7 +36,29 @@ class QuicServerConfigProtobuf; class StrikeRegister; class StrikeRegisterClient; -struct ClientHelloInfo; +// ClientHelloInfo contains information about a client hello message that is +// only kept for as long as it's being processed. +struct ClientHelloInfo { + ClientHelloInfo(const IPEndPoint& in_client_ip, QuicWallTime in_now); + ~ClientHelloInfo(); + + // Inputs to EvaluateClientHello. + const IPEndPoint client_ip; + const QuicWallTime now; + + // Outputs from EvaluateClientHello. + bool valid_source_address_token; + bool client_nonce_well_formed; + bool unique; + base::StringPiece sni; + base::StringPiece client_nonce; + base::StringPiece server_nonce; + base::StringPiece user_agent_id; + + // Errors from EvaluateClientHello. + std::vector<uint32> reject_reasons; + COMPILE_ASSERT(sizeof(QuicTag) == sizeof(uint32), header_out_of_sync); +}; namespace test { class QuicCryptoServerConfigPeer; @@ -58,7 +80,20 @@ class NET_EXPORT_PRIVATE ValidateClientHelloResultCallback { public: // Opaque token that holds information about the client_hello and // its validity. Can be interpreted by calling ProcessClientHello. - struct Result; + struct Result { + Result(const CryptoHandshakeMessage& in_client_hello, + IPEndPoint in_client_ip, + QuicWallTime in_now); + ~Result(); + + CryptoHandshakeMessage client_hello; + ClientHelloInfo info; + QuicErrorCode error_code; + std::string error_details; + + // Populated if the CHLO STK contained a CachedNetworkParameters proto. + CachedNetworkParameters cached_network_params; + }; ValidateClientHelloResultCallback(); virtual ~ValidateClientHelloResultCallback(); @@ -386,6 +421,7 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig { const Config& config, const CryptoHandshakeMessage& client_hello, const ClientHelloInfo& info, + const CachedNetworkParameters& cached_network_params, QuicRandom* rand, QuicCryptoNegotiatedParameters *params, CryptoHandshakeMessage* out) const; @@ -407,10 +443,14 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig { // ValidateSourceAddressToken returns HANDSHAKE_OK if the source address token // in |token| is a valid and timely token for the IP address |ip| given that // the current time is |now|. Otherwise it returns the reason for failure. - HandshakeFailureReason ValidateSourceAddressToken(const Config& config, - base::StringPiece token, - const IPEndPoint& ip, - QuicWallTime now) const; + // |cached_network_params| is populated if |token| contains a + // CachedNetworkParameters proto. + HandshakeFailureReason ValidateSourceAddressToken( + const Config& config, + base::StringPiece token, + const IPEndPoint& ip, + QuicWallTime now, + CachedNetworkParameters* cached_network_params) const; // NewServerNonce generates and encrypts a random nonce. std::string NewServerNonce(QuicRandom* rand, QuicWallTime now) const; diff --git a/net/quic/crypto/quic_crypto_server_config_test.cc b/net/quic/crypto/quic_crypto_server_config_test.cc index 179b6ac..59d6cf4 100644 --- a/net/quic/crypto/quic_crypto_server_config_test.cc +++ b/net/quic/crypto/quic_crypto_server_config_test.cc @@ -13,6 +13,7 @@ #include "net/quic/crypto/crypto_server_config_protobuf.h" #include "net/quic/crypto/quic_random.h" #include "net/quic/crypto/strike_register_client.h" +#include "net/quic/quic_flags.h" #include "net/quic/quic_time.h" #include "net/quic/test_tools/mock_clock.h" #include "net/quic/test_tools/quic_test_utils.h" @@ -52,19 +53,37 @@ class QuicCryptoServerConfigPeer { string NewSourceAddressToken( string config_id, - IPEndPoint ip, + const IPEndPoint& ip, QuicRandom* rand, QuicWallTime now) { + return NewSourceAddressToken(config_id, ip, rand, now, NULL); + } + + string NewSourceAddressToken( + string config_id, + const IPEndPoint& ip, + QuicRandom* rand, + QuicWallTime now, + CachedNetworkParameters* cached_network_params) { return server_config_->NewSourceAddressToken( - *GetConfig(config_id), ip, rand, now, nullptr); + *GetConfig(config_id), ip, rand, now, cached_network_params); } HandshakeFailureReason ValidateSourceAddressToken(string config_id, StringPiece srct, - IPEndPoint ip, + const IPEndPoint& ip, QuicWallTime now) { + return ValidateSourceAddressToken(config_id, srct, ip, now, NULL); + } + + HandshakeFailureReason ValidateSourceAddressToken( + string config_id, + StringPiece srct, + const IPEndPoint& ip, + QuicWallTime now, + CachedNetworkParameters* cached_network_params) { return server_config_->ValidateSourceAddressToken( - *GetConfig(config_id), srct, ip, now); + *GetConfig(config_id), srct, ip, now, cached_network_params); } string NewServerNonce(QuicRandom* rand, QuicWallTime now) const { @@ -241,6 +260,8 @@ TEST(QuicCryptoServerConfigTest, GetOrbitIsCalledWithoutTheStrikeRegisterLock) { } TEST(QuicCryptoServerConfigTest, SourceAddressTokens) { + ValueRestore<bool> old_flag(&FLAGS_quic_store_cached_network_params_from_chlo, + true); const string kPrimary = "<primary>"; const string kOverride = "Config with custom source address token key"; @@ -329,6 +350,21 @@ TEST(QuicCryptoServerConfigTest, SourceAddressTokens) { now = original_time.Subtract(QuicTime::Delta::FromSeconds(3600 * 2)); DCHECK_EQ(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE, peer.ValidateSourceAddressToken(kPrimary, token4, ip4, now)); + + // Make sure that if the source address token contains CachedNetworkParameters + // that this gets written to ValidateSourceAddressToken output argument. + CachedNetworkParameters cached_network_params_input; + cached_network_params_input.set_bandwidth_estimate_bytes_per_second(1234); + const string token4_with_cached_network_params = peer.NewSourceAddressToken( + kPrimary, ip4, rand, now, &cached_network_params_input); + + CachedNetworkParameters cached_network_params_output; + EXPECT_NE(cached_network_params_output, cached_network_params_input); + peer.ValidateSourceAddressToken(kPrimary, token4_with_cached_network_params, + ip4, now, &cached_network_params_output); + // TODO(rtenneti): For server, enable the following check after serialization + // of optional CachedNetworkParameters is implemented. + // EXPECT_EQ(cached_network_params_output, cached_network_params_input); } TEST(QuicCryptoServerConfigTest, ValidateServerNonce) { diff --git a/net/quic/crypto/source_address_token.cc b/net/quic/crypto/source_address_token.cc index f20c343..7ac43f0 100644 --- a/net/quic/crypto/source_address_token.cc +++ b/net/quic/crypto/source_address_token.cc @@ -14,13 +14,39 @@ using std::vector; namespace net { -CachedNetworkParameters::CachedNetworkParameters() { +CachedNetworkParameters::CachedNetworkParameters() + : bandwidth_estimate_bytes_per_second_(0), + max_bandwidth_estimate_bytes_per_second_(0), + max_bandwidth_timestamp_seconds_(0), + min_rtt_ms_(0), + previous_connection_state_(0), + timestamp_(0) { } CachedNetworkParameters::~CachedNetworkParameters() { } -SourceAddressToken::SourceAddressToken() { +bool CachedNetworkParameters::operator==( + const CachedNetworkParameters& other) const { + return serving_region_ == other.serving_region_ && + bandwidth_estimate_bytes_per_second_ == + other.bandwidth_estimate_bytes_per_second_ && + max_bandwidth_estimate_bytes_per_second_ == + other.max_bandwidth_estimate_bytes_per_second_ && + max_bandwidth_timestamp_seconds_ == + other.max_bandwidth_timestamp_seconds_ && + min_rtt_ms_ == other.min_rtt_ms_ && + previous_connection_state_ == other.previous_connection_state_ && + timestamp_ == other.timestamp_; +} + +bool CachedNetworkParameters::operator!=( + const CachedNetworkParameters& other) const { + return !(*this == other); +} + +SourceAddressToken::SourceAddressToken() + : has_cached_network_parameters_(false) { } SourceAddressToken::~SourceAddressToken() { diff --git a/net/quic/crypto/source_address_token.h b/net/quic/crypto/source_address_token.h index 1101351..76c3454d 100644 --- a/net/quic/crypto/source_address_token.h +++ b/net/quic/crypto/source_address_token.h @@ -28,6 +28,9 @@ class NET_EXPORT_PRIVATE CachedNetworkParameters { CachedNetworkParameters(); ~CachedNetworkParameters(); + bool operator==(const CachedNetworkParameters& other) const; + bool operator!=(const CachedNetworkParameters& other) const; + std::string serving_region() const { return serving_region_; } @@ -133,6 +136,10 @@ class NET_EXPORT_PRIVATE SourceAddressToken { void set_cached_network_parameters( const CachedNetworkParameters& cached_network_parameters) { cached_network_parameters_ = cached_network_parameters; + has_cached_network_parameters_ = true; + } + bool has_cached_network_parameters() const { + return has_cached_network_parameters_; } private: @@ -146,6 +153,9 @@ class NET_EXPORT_PRIVATE SourceAddressToken { // The server can provide estimated network parameters to be used for // initial parameter selection in future connections. CachedNetworkParameters cached_network_parameters_; + // TODO(rtenneti): Delete |has_cached_network_parameters_| after we convert + // SourceAddressToken to protobuf. + bool has_cached_network_parameters_; DISALLOW_COPY_AND_ASSIGN(SourceAddressToken); }; diff --git a/net/quic/quic_client_session_test.cc b/net/quic/quic_client_session_test.cc index 834ebe6..b1cfe3d 100644 --- a/net/quic/quic_client_session_test.cc +++ b/net/quic/quic_client_session_test.cc @@ -51,8 +51,6 @@ class QuicClientSessionTest : public ::testing::TestWithParam<QuicVersion> { session_.InitializeSession(QuicServerId(kServerHostname, kServerPort, false, PRIVACY_MODE_DISABLED), &crypto_config_, nullptr); - session_.config()->SetDefaults(); - crypto_config_.SetDefaults(); } virtual void TearDown() override { diff --git a/net/quic/quic_config.cc b/net/quic/quic_config.cc index 5330b7c..7b7976c 100644 --- a/net/quic/quic_config.cc +++ b/net/quic/quic_config.cc @@ -427,6 +427,7 @@ QuicErrorCode QuicFixedTagVector::ProcessPeerHello( QuicConfig::QuicConfig() : max_time_before_crypto_handshake_(QuicTime::Delta::Zero()), max_idle_time_before_crypto_handshake_(QuicTime::Delta::Zero()), + max_undecryptable_packets_(0), congestion_feedback_(kCGST, PRESENCE_REQUIRED), connection_options_(kCOPT, PRESENCE_OPTIONAL), idle_connection_state_lifetime_seconds_(kICSL, PRESENCE_REQUIRED), @@ -443,6 +444,7 @@ QuicConfig::QuicConfig() // QUIC_VERSION_19. initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL), socket_receive_buffer_(kSRBF, PRESENCE_OPTIONAL) { + SetDefaults(); } QuicConfig::~QuicConfig() {} @@ -643,6 +645,7 @@ void QuicConfig::SetDefaults() { QuicTime::Delta::FromSeconds(kMaxTimeForCryptoHandshakeSecs); max_idle_time_before_crypto_handshake_ = QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs); + max_undecryptable_packets_ = kDefaultMaxUndecryptablePackets; SetInitialFlowControlWindowToSend(kDefaultFlowControlSendWindow); SetInitialStreamFlowControlWindowToSend(kDefaultFlowControlSendWindow); diff --git a/net/quic/quic_config.h b/net/quic/quic_config.h index a9681fb..7be4569 100644 --- a/net/quic/quic_config.h +++ b/net/quic/quic_config.h @@ -304,6 +304,14 @@ class NET_EXPORT_PRIVATE QuicConfig { return max_idle_time_before_crypto_handshake_; } + void set_max_undecryptable_packets(size_t max_undecryptable_packets) { + max_undecryptable_packets_ = max_undecryptable_packets; + } + + size_t max_undecryptable_packets() const { + return max_undecryptable_packets_; + } + // Sets the peer's default initial congestion window in packets. void SetInitialCongestionWindowToSend(size_t initial_window); @@ -362,9 +370,6 @@ class NET_EXPORT_PRIVATE QuicConfig { bool negotiated() const; - // SetDefaults sets the members to sensible, default values. - void SetDefaults(); - // ToHandshakeMessage serialises the settings in this object as a series of // tags /value pairs and adds them to |out|. void ToHandshakeMessage(CryptoHandshakeMessage* out) const; @@ -378,11 +383,16 @@ class NET_EXPORT_PRIVATE QuicConfig { private: friend class test::QuicConfigPeer; + // SetDefaults sets the members to sensible, default values. + void SetDefaults(); + // Configurations options that are not negotiated. // Maximum time the session can be alive before crypto handshake is finished. QuicTime::Delta max_time_before_crypto_handshake_; // Maximum idle time before the crypto handshake has completed. QuicTime::Delta max_idle_time_before_crypto_handshake_; + // Maximum number of undecryptable packets stored before CHLO/SHLO. + size_t max_undecryptable_packets_; // Congestion control feedback type. QuicNegotiableTag congestion_feedback_; diff --git a/net/quic/quic_config_test.cc b/net/quic/quic_config_test.cc index 2263e44..914b137 100644 --- a/net/quic/quic_config_test.cc +++ b/net/quic/quic_config_test.cc @@ -22,15 +22,10 @@ namespace { class QuicConfigTest : public ::testing::Test { protected: - QuicConfigTest() { - config_.SetDefaults(); - } - QuicConfig config_; }; TEST_F(QuicConfigTest, ToHandshakeMessage) { - config_.SetDefaults(); config_.SetInitialFlowControlWindowToSend( kInitialSessionFlowControlWindowForTest); config_.SetInitialStreamFlowControlWindowToSend( @@ -265,7 +260,6 @@ TEST_F(QuicConfigTest, MultipleNegotiatedValuesInVectorTag) { TEST_F(QuicConfigTest, NoOverLapInCGST) { QuicConfig server_config; - server_config.SetDefaults(); QuicTagVector cgst; cgst.push_back(kTBBR); server_config.SetCongestionFeedback(cgst, kTBBR); diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc index b4d0219..f684cf2 100644 --- a/net/quic/quic_connection.cc +++ b/net/quic/quic_connection.cc @@ -6,6 +6,7 @@ #include <string.h> #include <sys/types.h> + #include <algorithm> #include <iterator> #include <limits> @@ -53,10 +54,6 @@ const QuicPacketSequenceNumber kMaxPacketGap = 5000; // that this becomes limiting, we can revisit. const size_t kMaxFecGroups = 2; -// Limit the number of undecryptable packets we buffer in -// expectation of the CHLO/SHLO arriving. -const size_t kMaxUndecryptablePackets = 10; - // Maximum number of acks received before sending an ack in response. const size_t kMaxPacketsReceivedBeforeAckSend = 20; @@ -162,10 +159,10 @@ class PingAlarm : public QuicAlarm::Delegate { QuicConnection::QueuedPacket::QueuedPacket(SerializedPacket packet, EncryptionLevel level) - : serialized_packet(packet), - encryption_level(level), - transmission_type(NOT_RETRANSMISSION), - original_sequence_number(0) { + : serialized_packet(packet), + encryption_level(level), + transmission_type(NOT_RETRANSMISSION), + original_sequence_number(0) { } QuicConnection::QueuedPacket::QueuedPacket( @@ -204,6 +201,7 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id, last_decrypted_packet_level_(ENCRYPTION_NONE), largest_seen_packet_with_ack_(0), largest_seen_packet_with_stop_waiting_(0), + max_undecryptable_packets_(0), pending_version_negotiation_packet_(false), received_packet_manager_(&stats_), ack_queued_(false), @@ -271,6 +269,7 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) { SetIdleNetworkTimeout(config.IdleConnectionStateLifetime()); } sent_packet_manager_.SetFromConfig(config); + max_undecryptable_packets_ = config.max_undecryptable_packets(); } bool QuicConnection::SelectMutualVersion( @@ -1116,7 +1115,7 @@ void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address, // because the CHLO or SHLO packet was lost. if (framer_.error() == QUIC_DECRYPTION_FAILURE) { if (encryption_level_ != ENCRYPTION_FORWARD_SECURE && - undecryptable_packets_.size() < kMaxUndecryptablePackets) { + undecryptable_packets_.size() < max_undecryptable_packets_) { QueueUndecryptablePacket(packet); } else if (debug_visitor_.get() != nullptr) { debug_visitor_->OnUndecryptablePacket(); @@ -1176,8 +1175,7 @@ void QuicConnection::OnCanWrite() { return; } - { // Limit the scope of the bundler. - // Set |include_ack| to false in bundler; ack inclusion happens elsewhere. + { // Limit the scope of the bundler. ACK inclusion happens elsewhere. ScopedPacketBundler bundler(this, NO_ACK); visitor_->OnCanWrite(); } @@ -1322,7 +1320,8 @@ bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) { // If the scheduler requires a delay, then we can not send this packet now. if (!delay.IsZero()) { send_alarm_->Update(now.Add(delay), QuicTime::Delta::FromMilliseconds(1)); - DVLOG(1) << "Delaying sending."; + DVLOG(1) << ENDPOINT << "Delaying sending " << delay.ToMilliseconds() + << "ms"; return false; } send_alarm_->Cancel(); @@ -1408,15 +1407,6 @@ bool QuicConnection::WritePacketInner(QueuedPacket* packet) { if (result.error_code == ERR_IO_PENDING) { DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status); } - if (debug_visitor_.get() != nullptr) { - // Pass the write result to the visitor. - debug_visitor_->OnPacketSent(sequence_number, - packet->original_sequence_number, - packet->encryption_level, - packet->transmission_type, - *encrypted, - result); - } if (result.status == WRITE_STATUS_BLOCKED) { visitor_->OnWriteBlocked(); @@ -1429,6 +1419,15 @@ bool QuicConnection::WritePacketInner(QueuedPacket* packet) { } } QuicTime now = clock_->Now(); + if (result.status != WRITE_STATUS_ERROR && debug_visitor_.get() != nullptr) { + // Pass the write result to the visitor. + debug_visitor_->OnPacketSent(packet->serialized_packet, + packet->original_sequence_number, + packet->encryption_level, + packet->transmission_type, + *encrypted, + now); + } if (packet->transmission_type == NOT_RETRANSMISSION) { time_of_last_sent_new_packet_ = now; } @@ -1857,7 +1856,7 @@ void QuicConnection::SetIdleNetworkTimeout(QuicTime::Delta timeout) { // Adjust the idle timeout on client and server to prevent clients from // sending requests to servers which have already closed the connection. if (is_server_) { - timeout = timeout.Add(QuicTime::Delta::FromSeconds(1)); + timeout = timeout.Add(QuicTime::Delta::FromSeconds(3)); } else if (timeout > QuicTime::Delta::FromSeconds(1)) { timeout = timeout.Subtract(QuicTime::Delta::FromSeconds(1)); } @@ -1895,7 +1894,7 @@ void QuicConnection::SetNetworkTimeouts(QuicTime::Delta overall_timeout, // Adjust the idle timeout on client and server to prevent clients from // sending requests to servers which have already closed the connection. if (is_server_) { - idle_timeout = idle_timeout.Add(QuicTime::Delta::FromSeconds(1)); + idle_timeout = idle_timeout.Add(QuicTime::Delta::FromSeconds(3)); } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) { idle_timeout = idle_timeout.Subtract(QuicTime::Delta::FromSeconds(1)); } diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h index 107a531..fa117f8 100644 --- a/net/quic/quic_connection.h +++ b/net/quic/quic_connection.h @@ -124,12 +124,12 @@ class NET_EXPORT_PRIVATE QuicConnectionDebugVisitor virtual ~QuicConnectionDebugVisitor() {} // Called when a packet has been sent. - virtual void OnPacketSent(QuicPacketSequenceNumber sequence_number, + virtual void OnPacketSent(const SerializedPacket& serialized_packet, QuicPacketSequenceNumber original_sequence_number, EncryptionLevel level, TransmissionType transmission_type, const QuicEncryptedPacket& packet, - WriteResult result) {} + QuicTime sent_time) {} // Called when a packet has been received, but before it is // validated or parsed. @@ -713,6 +713,9 @@ class NET_EXPORT_PRIVATE QuicConnection // sent with the INITIAL encryption and the CHLO message was lost. std::deque<QuicEncryptedPacket*> undecryptable_packets_; + // Maximum number of undecryptable packets the connection will store. + size_t max_undecryptable_packets_; + // When the version negotiation packet could not be sent because the socket // was not writable, this is set to true. bool pending_version_negotiation_packet_; diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc index 4e40417..8a544b2 100644 --- a/net/quic/quic_connection_logger.cc +++ b/net/quic/quic_connection_logger.cc @@ -46,24 +46,22 @@ base::Value* NetLogQuicPacketCallback(const IPEndPoint* self_address, } base::Value* NetLogQuicPacketSentCallback( - QuicPacketSequenceNumber sequence_number, + const SerializedPacket& serialized_packet, QuicPacketSequenceNumber original_sequence_number, EncryptionLevel level, TransmissionType transmission_type, size_t packet_size, - WriteResult result, + QuicTime sent_time, NetLog::LogLevel /* log_level */) { base::DictionaryValue* dict = new base::DictionaryValue(); dict->SetInteger("encryption_level", level); dict->SetInteger("transmission_type", transmission_type); dict->SetString("packet_sequence_number", - base::Uint64ToString(sequence_number)); + base::Uint64ToString(serialized_packet.sequence_number)); dict->SetString("original_sequence_number", base::Uint64ToString(original_sequence_number)); dict->SetInteger("size", packet_size); - if (result.status != WRITE_STATUS_OK) { - dict->SetInteger("net_error", result.error_code); - } + dict->SetInteger("sent_time_us", sent_time.ToDebuggingValue()); return dict; } @@ -463,17 +461,17 @@ void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) { } void QuicConnectionLogger::OnPacketSent( - QuicPacketSequenceNumber sequence_number, + const SerializedPacket& serialized_packet, QuicPacketSequenceNumber original_sequence_number, EncryptionLevel level, TransmissionType transmission_type, const QuicEncryptedPacket& packet, - WriteResult result) { + QuicTime sent_time) { net_log_.AddEvent( NetLog::TYPE_QUIC_SESSION_PACKET_SENT, - base::Bind(&NetLogQuicPacketSentCallback, sequence_number, + base::Bind(&NetLogQuicPacketSentCallback, serialized_packet, original_sequence_number, level, transmission_type, - packet.length(), result)); + packet.length(), sent_time)); } void QuicConnectionLogger::OnPacketReceived(const IPEndPoint& self_address, diff --git a/net/quic/quic_connection_logger.h b/net/quic/quic_connection_logger.h index 3f30ebb..2d32b46 100644 --- a/net/quic/quic_connection_logger.h +++ b/net/quic/quic_connection_logger.h @@ -34,12 +34,12 @@ class NET_EXPORT_PRIVATE QuicConnectionLogger virtual void OnFrameAddedToPacket(const QuicFrame& frame) override; // QuicConnectionDebugVisitorInterface - virtual void OnPacketSent(QuicPacketSequenceNumber sequence_number, + virtual void OnPacketSent(const SerializedPacket& serialized_packet, QuicPacketSequenceNumber original_sequence_number, EncryptionLevel level, TransmissionType transmission_type, const QuicEncryptedPacket& packet, - WriteResult result) override; + QuicTime sent_time) override; virtual void OnPacketReceived(const IPEndPoint& self_address, const IPEndPoint& peer_address, const QuicEncryptedPacket& packet) override; diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc index 9e29ee1..b084428 100644 --- a/net/quic/quic_connection_test.cc +++ b/net/quic/quic_connection_test.cc @@ -2416,19 +2416,22 @@ TEST_P(QuicConnectionTest, RetransmitPacketsWithInitialEncryption) { } TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) { + // SetFromConfig is always called after construction from InitializeSession. + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + QuicConfig config; + connection_.SetFromConfig(config); EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); use_tagging_decrypter(); const uint8 tag = 0x07; framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag)); - // Process an encrypted packet which can not yet be decrypted - // which should result in the packet being buffered. + // Process an encrypted packet which can not yet be decrypted which should + // result in the packet being buffered. ProcessDataPacketAtLevel(1, 0, kEntropyFlag, ENCRYPTION_INITIAL); - // Transition to the new encryption state and process another - // encrypted packet which should result in the original packet being - // processed. + // Transition to the new encryption state and process another encrypted packet + // which should result in the original packet being processed. connection_.SetDecrypter(new StrictTaggingDecrypter(tag), ENCRYPTION_INITIAL); connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL); @@ -2436,12 +2439,44 @@ TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) { EXPECT_CALL(visitor_, OnStreamFrames(_)).Times(2); ProcessDataPacketAtLevel(2, 0, kEntropyFlag, ENCRYPTION_INITIAL); - // Finally, process a third packet and note that we do not - // reprocess the buffered packet. + // Finally, process a third packet and note that we do not reprocess the + // buffered packet. EXPECT_CALL(visitor_, OnStreamFrames(_)).Times(1); ProcessDataPacketAtLevel(3, 0, kEntropyFlag, ENCRYPTION_INITIAL); } +TEST_P(QuicConnectionTest, Buffer100NonDecryptablePackets) { + // SetFromConfig is always called after construction from InitializeSession. + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + QuicConfig config; + config.set_max_undecryptable_packets(100); + connection_.SetFromConfig(config); + EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); + use_tagging_decrypter(); + + const uint8 tag = 0x07; + framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag)); + + // Process an encrypted packet which can not yet be decrypted which should + // result in the packet being buffered. + for (QuicPacketSequenceNumber i = 1; i <= 100; ++i) { + ProcessDataPacketAtLevel(i, 0, kEntropyFlag, ENCRYPTION_INITIAL); + } + + // Transition to the new encryption state and process another encrypted packet + // which should result in the original packets being processed. + connection_.SetDecrypter(new StrictTaggingDecrypter(tag), ENCRYPTION_INITIAL); + connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL); + connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag)); + EXPECT_CALL(visitor_, OnStreamFrames(_)).Times(101); + ProcessDataPacketAtLevel(101, 0, kEntropyFlag, ENCRYPTION_INITIAL); + + // Finally, process a third packet and note that we do not reprocess the + // buffered packet. + EXPECT_CALL(visitor_, OnStreamFrames(_)).Times(1); + ProcessDataPacketAtLevel(102, 0, kEntropyFlag, ENCRYPTION_INITIAL); +} + TEST_P(QuicConnectionTest, TestRetransmitOrder) { QuicByteCount first_packet_size; EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).WillOnce( @@ -2682,7 +2717,6 @@ TEST_P(QuicConnectionTest, InitialTimeout) { // SetFromConfig sets the initial timeouts before negotiation. EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); QuicConfig config; - config.SetDefaults(); connection_.SetFromConfig(config); // Subtract a second from the idle timeout on the client side. QuicTime default_timeout = clock_.ApproximateNow().Add( @@ -2835,7 +2869,6 @@ TEST_P(QuicConnectionTest, TimeoutAfterSend) { EXPECT_TRUE(connection_.connected()); EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); QuicConfig config; - config.SetDefaults(); connection_.SetFromConfig(config); const QuicTime::Delta initial_idle_timeout = @@ -3924,12 +3957,12 @@ class MockQuicConnectionDebugVisitor void(const QuicFrame&)); MOCK_METHOD6(OnPacketSent, - void(QuicPacketSequenceNumber, + void(const SerializedPacket&, QuicPacketSequenceNumber, EncryptionLevel, TransmissionType, const QuicEncryptedPacket&, - WriteResult)); + QuicTime)); MOCK_METHOD3(OnPacketReceived, void(const IPEndPoint&, diff --git a/net/quic/quic_crypto_client_stream_test.cc b/net/quic/quic_crypto_client_stream_test.cc index 5a8b08c..1df2313 100644 --- a/net/quic/quic_crypto_client_stream_test.cc +++ b/net/quic/quic_crypto_client_stream_test.cc @@ -34,8 +34,6 @@ class QuicCryptoClientStreamTest : public ::testing::Test { stream_(new QuicCryptoClientStream(server_id_, session_.get(), nullptr, &crypto_config_)) { session_->SetCryptoStream(stream_.get()); - session_->config()->SetDefaults(); - crypto_config_.SetDefaults(); } void CompleteCryptoHandshake() { @@ -127,7 +125,6 @@ TEST_F(QuicCryptoClientStreamTest, ExpiredServerConfig) { &crypto_config_)); session_->SetCryptoStream(stream_.get()); - session_->config()->SetDefaults(); // Advance time 5 years to ensure that we pass the expiry time of the cached // server config. diff --git a/net/quic/quic_crypto_server_stream.cc b/net/quic/quic_crypto_server_stream.cc index eebab90..e912c32 100644 --- a/net/quic/quic_crypto_server_stream.cc +++ b/net/quic/quic_crypto_server_stream.cc @@ -11,6 +11,7 @@ #include "net/quic/crypto/quic_crypto_server_config.h" #include "net/quic/crypto/source_address_token.h" #include "net/quic/quic_config.h" +#include "net/quic/quic_flags.h" #include "net/quic/quic_protocol.h" #include "net/quic/quic_session.h" @@ -152,11 +153,12 @@ void QuicCryptoServerStream::FinishProcessingHandshakeMessage( // Now that the handshake is complete, send an updated server config and // source-address token to the client. - SendServerConfigUpdate(nullptr); + SendServerConfigUpdate(previous_cached_network_params_.get(), true); } void QuicCryptoServerStream::SendServerConfigUpdate( - const CachedNetworkParameters* cached_network_params) { + const CachedNetworkParameters* cached_network_params, + bool on_handshake_complete) { if (session()->connection()->version() <= QUIC_VERSION_21 || !handshake_confirmed_) { return; @@ -174,7 +176,8 @@ void QuicCryptoServerStream::SendServerConfigUpdate( return; } - DVLOG(1) << "Server: Sending server config update: " + DVLOG(1) << "Server: Sending server config update" + << (on_handshake_complete ? " immediately after handshake: " : ": ") << server_config_update_message.DebugString(); const QuicData& data = server_config_update_message.GetSerialized(); WriteOrBufferData(string(data.data(), data.length()), false, nullptr); @@ -221,6 +224,13 @@ QuicErrorCode QuicCryptoServerStream::ProcessClientHello( const ValidateClientHelloResultCallback::Result& result, CryptoHandshakeMessage* reply, string* error_details) { + // Store the bandwidth estimate from the client. + if (FLAGS_quic_store_cached_network_params_from_chlo && + result.cached_network_params.bandwidth_estimate_bytes_per_second() > 0) { + previous_cached_network_params_.reset( + new CachedNetworkParameters(result.cached_network_params)); + } + return crypto_config_.ProcessClientHello( result, session()->connection()->connection_id(), diff --git a/net/quic/quic_crypto_server_stream.h b/net/quic/quic_crypto_server_stream.h index 611f8d9..5d55564 100644 --- a/net/quic/quic_crypto_server_stream.h +++ b/net/quic/quic_crypto_server_stream.h @@ -74,8 +74,11 @@ class NET_EXPORT_PRIVATE QuicCryptoServerStream : public QuicCryptoStream { } // Sends the latest server config and source-address token to the client. + // |on_handshake_complete| is true when this is called immediately after + // handshake completes, and should be false for subsequent updates. virtual void SendServerConfigUpdate( - const CachedNetworkParameters* cached_network_params); + const CachedNetworkParameters* cached_network_params, + bool on_handshake_complete); // Called by the ServerHello AckNotifier once the SHLO has been ACKed by the // client. @@ -133,6 +136,11 @@ class NET_EXPORT_PRIVATE QuicCryptoServerStream : public QuicCryptoStream { // Number of server config update (SCUP) messages sent by this stream. int num_server_config_update_messages_sent_; + // If the client provides CachedNetworkParameters in the STK in the CHLO, then + // store here, and send back in future STKs if we have no better bandwidth + // estimate to send. + scoped_ptr<CachedNetworkParameters> previous_cached_network_params_; + DISALLOW_COPY_AND_ASSIGN(QuicCryptoServerStream); }; diff --git a/net/quic/quic_crypto_server_stream_test.cc b/net/quic/quic_crypto_server_stream_test.cc index 6ce059b..38b4a57 100644 --- a/net/quic/quic_crypto_server_stream_test.cc +++ b/net/quic/quic_crypto_server_stream_test.cc @@ -61,8 +61,6 @@ class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> { QuicRandom::GetInstance()), stream_(crypto_config_, &session_), strike_register_client_(nullptr) { - config_.SetDefaults(); - session_.config()->SetDefaults(); session_.SetCryptoStream(&stream_); // We advance the clock initially because the default time is zero and the // strike register worries that we've just overflowed a uint32 time. @@ -141,11 +139,9 @@ TEST_P(QuicCryptoServerStreamTest, ZeroRTT) { server_conn->AdvanceTime(QuicTime::Delta::FromSeconds(100000)); QuicConfig client_config; - client_config.SetDefaults(); scoped_ptr<TestClientSession> client_session( new TestClientSession(client_conn, client_config)); QuicCryptoClientConfig client_crypto_config; - client_crypto_config.SetDefaults(); QuicServerId server_id(kServerHostname, kServerPort, false, PRIVACY_MODE_DISABLED); @@ -277,7 +273,7 @@ TEST_P(QuicCryptoServerStreamTest, ChannelIDAsync) { TEST_P(QuicCryptoServerStreamTest, OnlySendSCUPAfterHandshakeComplete) { // An attempt to send a SCUP before completing handshake should fail. - stream_.SendServerConfigUpdate(nullptr); + stream_.SendServerConfigUpdate(nullptr, false); EXPECT_EQ(0, stream_.num_server_config_update_messages_sent()); } diff --git a/net/quic/quic_end_to_end_unittest.cc b/net/quic/quic_end_to_end_unittest.cc index ad0643da..b589bc6 100644 --- a/net/quic/quic_end_to_end_unittest.cc +++ b/net/quic/quic_end_to_end_unittest.cc @@ -133,7 +133,6 @@ class QuicEndToEndTest : public PlatformTest { net::IPAddressNumber ip; CHECK(net::ParseIPLiteralToNumber("127.0.0.1", &ip)); server_address_ = IPEndPoint(ip, 0); - server_config_.SetDefaults(); server_config_.SetInitialFlowControlWindowToSend( kInitialSessionFlowControlWindowForTest); server_config_.SetInitialStreamFlowControlWindowToSend( diff --git a/net/quic/quic_flags.cc b/net/quic/quic_flags.cc index 864e12b..9a49a34 100644 --- a/net/quic/quic_flags.cc +++ b/net/quic/quic_flags.cc @@ -46,3 +46,7 @@ bool FLAGS_quic_timeouts_only_from_alarms = true; // If true, then QUIC connections will set both idle and overall timeouts in a // single method. bool FLAGS_quic_unified_timeouts = false; + +// If true, store any CachedNetworkParams that are provided in the STK from the +// CHLO. +bool FLAGS_quic_store_cached_network_params_from_chlo = false; diff --git a/net/quic/quic_flags.h b/net/quic/quic_flags.h index f1fea1e..7693260 100644 --- a/net/quic/quic_flags.h +++ b/net/quic/quic_flags.h @@ -18,5 +18,6 @@ NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_bbr_congestion_control; NET_EXPORT_PRIVATE extern bool FLAGS_quic_allow_more_open_streams; NET_EXPORT_PRIVATE extern bool FLAGS_quic_timeouts_only_from_alarms; NET_EXPORT_PRIVATE extern bool FLAGS_quic_unified_timeouts; +NET_EXPORT_PRIVATE extern bool FLAGS_quic_store_cached_network_params_from_chlo; #endif // NET_QUIC_QUIC_FLAGS_H_ diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc index 35321d9..b6ecc77 100644 --- a/net/quic/quic_http_stream_test.cc +++ b/net/quic/quic_http_stream_test.cc @@ -225,7 +225,6 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> { connection_->set_visitor(&visitor_); connection_->SetSendAlgorithm(send_algorithm_); connection_->SetReceiveAlgorithm(receive_algorithm_); - crypto_config_.SetDefaults(); session_.reset( new QuicClientSession(connection_, scoped_ptr<DatagramClientSocket>(socket), diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h index 6a1bec5..afae9ba 100644 --- a/net/quic/quic_protocol.h +++ b/net/quic/quic_protocol.h @@ -117,6 +117,10 @@ const int64 kMaximumIdleTimeoutSecs = 60 * 10; // 10 minutes. // The default timeout for a connection until the crypto handshake succeeds. const int64 kMaxTimeForCryptoHandshakeSecs = 10; // 10 secs. +// Default limit on the number of undecryptable packets the connection buffers +// before the CHLO/SHLO arrive. +const size_t kDefaultMaxUndecryptablePackets = 10; + // Default ping timeout. const int64 kPingTimeoutSecs = 15; // 15 secs. diff --git a/net/quic/quic_received_packet_manager.cc b/net/quic/quic_received_packet_manager.cc index 255ce4d..944376c 100644 --- a/net/quic/quic_received_packet_manager.cc +++ b/net/quic/quic_received_packet_manager.cc @@ -229,14 +229,11 @@ void QuicReceivedPacketManager::UpdateReceivedPacketInfo( return; } - if (approximate_now < time_largest_observed_) { - // Approximate now may well be "in the past". - ack_frame->delta_time_largest_observed = QuicTime::Delta::Zero(); - return; - } - + // Ensure the delta is zero if approximate now is "in the past". ack_frame->delta_time_largest_observed = - approximate_now.Subtract(time_largest_observed_); + approximate_now < time_largest_observed_ ? + QuicTime::Delta::Zero() : + approximate_now.Subtract(time_largest_observed_); // Remove all packets that are too far from largest_observed to express. received_packet_times_.remove_if(isTooLarge(ack_frame_.largest_observed)); diff --git a/net/quic/quic_received_packet_manager_test.cc b/net/quic/quic_received_packet_manager_test.cc index 9e8c128..396c8ee 100644 --- a/net/quic/quic_received_packet_manager_test.cc +++ b/net/quic/quic_received_packet_manager_test.cc @@ -314,6 +314,7 @@ TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedPacketInfo) { // When UpdateReceivedPacketInfo with a time earlier than the time of the // largest observed packet, make sure that the delta is 0, not negative. EXPECT_EQ(QuicTime::Delta::Zero(), ack.delta_time_largest_observed); + EXPECT_FALSE(ack.received_packet_times.empty()); QuicTime four_ms = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(4)); received_manager_.UpdateReceivedPacketInfo(&ack, four_ms); diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc index a062827..f5b2c73 100644 --- a/net/quic/quic_sent_packet_manager.cc +++ b/net/quic/quic_sent_packet_manager.cc @@ -503,13 +503,6 @@ bool QuicSentPacketManager::OnPacketSent( DCHECK_LT(0u, sequence_number); DCHECK(!unacked_packets_.IsUnacked(sequence_number)); LOG_IF(DFATAL, bytes == 0) << "Cannot send empty packets."; - if (debug_delegate_ != nullptr) { - debug_delegate_->OnSentPacket(*serialized_packet, - original_sequence_number, - sent_time, - bytes, - transmission_type); - } if (original_sequence_number == 0) { if (serialized_packet->retransmittable_frames) { diff --git a/net/quic/quic_sent_packet_manager.h b/net/quic/quic_sent_packet_manager.h index 2b5f738..f5be3fd 100644 --- a/net/quic/quic_sent_packet_manager.h +++ b/net/quic/quic_sent_packet_manager.h @@ -51,13 +51,6 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager { TransmissionType transmission_type, QuicByteCount byte_size) {} - virtual void OnSentPacket( - const SerializedPacket& packet, - QuicPacketSequenceNumber original_sequence_number, - QuicTime sent_time, - QuicByteCount bytes, - TransmissionType transmission_type) {} - virtual void OnIncomingAck( const QuicAckFrame& ack_frame, QuicTime ack_receive_time, diff --git a/net/quic/quic_server_bin.cc b/net/quic/quic_server_bin.cc index 63b85a7..320f3da 100644 --- a/net/quic/quic_server_bin.cc +++ b/net/quic/quic_server_bin.cc @@ -55,15 +55,12 @@ int main(int argc, char *argv[]) { } base::AtExitManager exit_manager; - base::MessageLoopForIO message_loop; net::IPAddressNumber ip; CHECK(net::ParseIPLiteralToNumber("::", &ip)); net::QuicConfig config; - config.SetDefaults(); - net::QuicServer server(config, net::QuicSupportedVersions()); int rc = server.Listen(net::IPEndPoint(ip, FLAGS_port)); diff --git a/net/quic/quic_server_session.cc b/net/quic/quic_server_session.cc index bacd59e..a61caaf 100644 --- a/net/quic/quic_server_session.cc +++ b/net/quic/quic_server_session.cc @@ -134,7 +134,7 @@ void QuicServerSession::OnCongestionWindowChange(QuicTime now) { cached_network_params.set_serving_region(serving_region_); } - crypto_stream_->SendServerConfigUpdate(&cached_network_params); + crypto_stream_->SendServerConfigUpdate(&cached_network_params, false); last_server_config_update_time_ = now; } diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc index ca68891..48564f0 100644 --- a/net/quic/quic_session_test.cc +++ b/net/quic/quic_session_test.cc @@ -581,11 +581,11 @@ TEST_P(QuicSessionTest, DoNotSendGoAwayTwice) { TEST_P(QuicSessionTest, IncreasedTimeoutAfterCryptoHandshake) { EXPECT_EQ((FLAGS_quic_unified_timeouts ? - kInitialIdleTimeoutSecs : kDefaultIdleTimeoutSecs) + 1, + kInitialIdleTimeoutSecs : kDefaultIdleTimeoutSecs) + 3, QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds()); CryptoHandshakeMessage msg; session_.GetCryptoStream()->OnHandshakeMessage(msg); - EXPECT_EQ(kMaximumIdleTimeoutSecs + 1, + EXPECT_EQ(kMaximumIdleTimeoutSecs + 3, QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds()); } diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index 39be0eb..687ea4c 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc @@ -70,6 +70,8 @@ const int32 kInitialReceiveWindowSize = 10 * 1024 * 1024; // 10MB const int32 kServerSecureInitialCongestionWindow = 32; // Be conservative, and just use double a typical TCP ICWND for HTTP. const int32 kServerInecureInitialCongestionWindow = 20; +// Set the maximum number of undecryptable packets the connection will store. +const int32 kMaxUndecryptablePackets = 100; const char kDummyHostname[] = "quic.global.props"; const uint16 kDummyPort = 0; @@ -90,7 +92,6 @@ bool IsEcdsaSupported() { QuicConfig InitializeQuicConfig(const QuicTagVector& connection_options) { QuicConfig config; - config.SetDefaults(); config.SetIdleConnectionStateLifetime( QuicTime::Delta::FromSeconds(kIdleConnectionTimeoutSeconds), QuicTime::Delta::FromSeconds(kIdleConnectionTimeoutSeconds)); @@ -511,7 +512,6 @@ QuicStreamFactory::QuicStreamFactory( check_persisted_supports_quic_(true), weak_factory_(this) { DCHECK(transport_security_state_); - crypto_config_.SetDefaults(); crypto_config_.set_user_agent_id(user_agent_id); crypto_config_.AddCanonicalSuffix(".c.youtube.com"); crypto_config_.AddCanonicalSuffix(".googlevideo.com"); @@ -902,6 +902,7 @@ int QuicStreamFactory::CreateSession( config.SetInitialCongestionWindowToSend( server_id.is_https() ? kServerSecureInitialCongestionWindow : kServerInecureInitialCongestionWindow); + config.set_max_undecryptable_packets(kMaxUndecryptablePackets); config.SetInitialFlowControlWindowToSend(kInitialReceiveWindowSize); config.SetInitialStreamFlowControlWindowToSend(kInitialReceiveWindowSize); config.SetInitialSessionFlowControlWindowToSend(kInitialReceiveWindowSize); diff --git a/net/quic/test_tools/crypto_test_utils.cc b/net/quic/test_tools/crypto_test_utils.cc index fe7e872..9f4dc8b 100644 --- a/net/quic/test_tools/crypto_test_utils.cc +++ b/net/quic/test_tools/crypto_test_utils.cc @@ -219,8 +219,6 @@ int CryptoTestUtils::HandshakeWithFakeClient( TestClientSession client_session(client_conn, DefaultQuicConfig()); QuicCryptoClientConfig crypto_config; - client_session.config()->SetDefaults(); - crypto_config.SetDefaults(); if (!options.dont_verify_certs) { // TODO(wtc): replace this with ProofVerifierForTesting() when we have // a working ProofSourceForTesting(). @@ -273,7 +271,6 @@ void CryptoTestUtils::SetupCryptoServerConfigForTest( QuicRandom* rand, QuicConfig* config, QuicCryptoServerConfig* crypto_config) { - config->SetDefaults(); QuicCryptoServerConfig::ConfigOptions options; options.channel_id_enabled = true; scoped_ptr<CryptoHandshakeMessage> scfg( diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc index f033bff..6cdd02a 100644 --- a/net/quic/test_tools/quic_test_utils.cc +++ b/net/quic/test_tools/quic_test_utils.cc @@ -609,7 +609,6 @@ MockEntropyCalculator::~MockEntropyCalculator() {} QuicConfig DefaultQuicConfig() { QuicConfig config; - config.SetDefaults(); config.SetInitialFlowControlWindowToSend( kInitialSessionFlowControlWindowForTest); config.SetInitialStreamFlowControlWindowToSend( diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc index 024f467..f29af96 100644 --- a/net/tools/quic/end_to_end_test.cc +++ b/net/tools/quic/end_to_end_test.cc @@ -198,9 +198,6 @@ class EndToEndTest : public ::testing::TestWithParam<TestParams> { VLOG(1) << "Using Configuration: " << GetParam(); - client_config_.SetDefaults(); - server_config_.SetDefaults(); - // Use different flow control windows for client/server. client_config_.SetInitialFlowControlWindowToSend( 2 * kInitialSessionFlowControlWindowForTest); diff --git a/net/tools/quic/quic_client.cc b/net/tools/quic/quic_client.cc index e70d8b8..7b2c994 100644 --- a/net/tools/quic/quic_client.cc +++ b/net/tools/quic/quic_client.cc @@ -49,7 +49,6 @@ QuicClient::QuicClient(IPEndPoint server_address, overflow_supported_(false), supported_versions_(supported_versions), print_response_(print_response) { - config_.SetDefaults(); } QuicClient::QuicClient(IPEndPoint server_address, @@ -86,7 +85,6 @@ bool QuicClient::Initialize() { DCHECK(!initialized_); epoll_server_->set_timeout_in_us(50 * 1000); - crypto_config_.SetDefaults(); if (!CreateUDPSocket()) { return false; diff --git a/net/tools/quic/quic_client_bin.cc b/net/tools/quic/quic_client_bin.cc index 4f76624..0f5c746 100644 --- a/net/tools/quic/quic_client_bin.cc +++ b/net/tools/quic/quic_client_bin.cc @@ -118,7 +118,6 @@ int main(int argc, char *argv[]) { << QuicVersionVectorToString(versions); net::EpollServer epoll_server; net::QuicConfig config; - config.SetDefaults(); // The default flow control window of 16 Kb is too small for practical // purposes. Set it to the specified value, which has a large default. diff --git a/net/tools/quic/quic_client_session_test.cc b/net/tools/quic/quic_client_session_test.cc index 2bd4315..467e29a 100644 --- a/net/tools/quic/quic_client_session_test.cc +++ b/net/tools/quic/quic_client_session_test.cc @@ -42,12 +42,10 @@ class ToolsQuicClientSessionTest ToolsQuicClientSessionTest() : connection_(new PacketSavingConnection(false, SupportedVersions(GetParam()))) { - crypto_config_.SetDefaults(); session_.reset(new QuicClientSession(DefaultQuicConfig(), connection_)); session_->InitializeSession( QuicServerId(kServerHostname, kPort, false, PRIVACY_MODE_DISABLED), &crypto_config_); - session_->config()->SetDefaults(); } void CompleteCryptoHandshake() { @@ -74,8 +72,7 @@ TEST_P(ToolsQuicClientSessionTest, MaxNumStreams) { // Initialize crypto before the client session will create a stream. CompleteCryptoHandshake(); - QuicSpdyClientStream* stream = - session_->CreateOutgoingDataStream(); + QuicSpdyClientStream* stream = session_->CreateOutgoingDataStream(); ASSERT_TRUE(stream); EXPECT_FALSE(session_->CreateOutgoingDataStream()); diff --git a/net/tools/quic/quic_server.cc b/net/tools/quic/quic_server.cc index 34beb3f..9d36909 100644 --- a/net/tools/quic/quic_server.cc +++ b/net/tools/quic/quic_server.cc @@ -48,8 +48,6 @@ QuicServer::QuicServer() use_recvmmsg_(false), crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()), supported_versions_(QuicSupportedVersions()) { - // Use hardcoded crypto parameters for now. - config_.SetDefaults(); Initialize(); } diff --git a/net/tools/quic/quic_server_session.cc b/net/tools/quic/quic_server_session.cc index cb56329..842c6ef 100644 --- a/net/tools/quic/quic_server_session.cc +++ b/net/tools/quic/quic_server_session.cc @@ -134,7 +134,7 @@ void QuicServerSession::OnCongestionWindowChange(QuicTime now) { cached_network_params.set_serving_region(serving_region_); } - crypto_stream_->SendServerConfigUpdate(&cached_network_params); + crypto_stream_->SendServerConfigUpdate(&cached_network_params, false); last_server_config_update_time_ = now; } diff --git a/net/tools/quic/quic_server_session_test.cc b/net/tools/quic/quic_server_session_test.cc index 4fc4157..72c65a8 100644 --- a/net/tools/quic/quic_server_session_test.cc +++ b/net/tools/quic/quic_server_session_test.cc @@ -68,7 +68,6 @@ class QuicServerSessionTest : public ::testing::TestWithParam<QuicVersion> { QuicServerSessionTest() : crypto_config_(QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance()) { - config_.SetDefaults(); config_.SetMaxStreamsPerConnection(kMaxStreamsForTest, kMaxStreamsForTest); config_.SetInitialFlowControlWindowToSend( @@ -295,8 +294,10 @@ class MockQuicCryptoServerStream : public QuicCryptoServerStream { : QuicCryptoServerStream(crypto_config, session) {} virtual ~MockQuicCryptoServerStream() {} - MOCK_METHOD1(SendServerConfigUpdate, - void(const CachedNetworkParameters* cached_network_parameters)); + MOCK_METHOD2(SendServerConfigUpdate, + void(const CachedNetworkParameters* cached_network_parameters, + bool on_handshake_complete)); + private: DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream); }; @@ -365,7 +366,7 @@ TEST_P(QuicServerSessionTest, BandwidthEstimates) { expected_network_params.set_serving_region(serving_region); EXPECT_CALL(*crypto_stream, - SendServerConfigUpdate(EqualsProto(expected_network_params))) + SendServerConfigUpdate(EqualsProto(expected_network_params), _)) .Times(1); session_->OnCongestionWindowChange(now); } diff --git a/net/tools/quic/quic_spdy_client_stream_test.cc b/net/tools/quic/quic_spdy_client_stream_test.cc index 058b204..090e2da 100644 --- a/net/tools/quic/quic_spdy_client_stream_test.cc +++ b/net/tools/quic/quic_spdy_client_stream_test.cc @@ -34,7 +34,6 @@ class QuicSpdyClientStreamTest : public TestWithParam<QuicVersion> { session_.InitializeSession( QuicServerId("example.com", 80, false, PRIVACY_MODE_DISABLED), &crypto_config_); - crypto_config_.SetDefaults(); headers_.SetResponseFirstlineFromStringPieces("HTTP/1.1", "200", "Ok"); headers_.ReplaceOrAppendHeader("content-length", "11"); |