In quic, do not extend idle time on undecryptable packets. protected by gfe2_reloadable_flag_quic_extend_idle_time_on_decryptable_packets. PiperOrigin-RevId: 310407777 Change-Id: Ibb071c6652e1568ad11ead178328b073fcadd60f
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc index 91b5c2b..6445fce 100644 --- a/quic/core/quic_connection.cc +++ b/quic/core/quic_connection.cc
@@ -299,6 +299,7 @@ handshake_timeout_(QuicTime::Delta::Infinite()), time_of_first_packet_sent_after_receiving_(QuicTime::Zero()), time_of_last_received_packet_(clock_->ApproximateNow()), + time_of_last_decryptable_packet_(time_of_last_received_packet_), sent_packet_manager_(perspective, clock_, random_generator_, @@ -845,6 +846,14 @@ // Address is validated by successfully processing a HANDSHAKE packet. address_validated_ = true; } + if (extend_idle_time_on_decryptable_packets_) { + QUIC_RELOADABLE_FLAG_COUNT(quic_extend_idle_time_on_decryptable_packets); + if (use_idle_network_detector_) { + idle_network_detector_.OnPacketReceived(time_of_last_received_packet_); + } else { + time_of_last_decryptable_packet_ = time_of_last_received_packet_; + } + } visitor_->OnPacketDecrypted(level); } @@ -1834,7 +1843,7 @@ << " too far from current time:" << clock_->ApproximateNow().ToDebuggingValue(); } - if (use_idle_network_detector_) { + if (!extend_idle_time_on_decryptable_packets_ && use_idle_network_detector_) { QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_idle_network_detector, 1, 6); idle_network_detector_.OnPacketReceived(packet.receipt_time()); } else { @@ -2414,7 +2423,7 @@ idle_network_detector_.OnPacketSent(packet_send_time); QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_idle_network_detector, 2, 6); } else if (time_of_first_packet_sent_after_receiving_ < - time_of_last_received_packet_) { + GetTimeOfLastReceivedPacket()) { // Update |time_of_first_packet_sent_after_receiving_| if this is the // first packet sent after the last packet was received. If it were // updated on every sent packet, then sending into a black hole might @@ -3192,7 +3201,7 @@ } QuicTime time_of_last_packet = - std::max(time_of_last_received_packet_, + std::max(GetTimeOfLastReceivedPacket(), time_of_first_packet_sent_after_receiving_); // |delta| can be < 0 as |now| is approximate time but |time_of_last_packet| @@ -3228,7 +3237,7 @@ void QuicConnection::SetTimeoutAlarm() { DCHECK(!use_idle_network_detector_); QuicTime time_of_last_packet = - std::max(time_of_last_received_packet_, + std::max(GetTimeOfLastReceivedPacket(), time_of_first_packet_sent_after_receiving_); QuicTime deadline = time_of_last_packet + idle_network_timeout_; @@ -4360,6 +4369,11 @@ if (use_idle_network_detector_) { return idle_network_detector_.time_of_last_received_packet(); } + if (extend_idle_time_on_decryptable_packets_) { + DCHECK(time_of_last_decryptable_packet_ == time_of_last_received_packet_ || + !last_packet_decrypted_); + return time_of_last_decryptable_packet_; + } return time_of_last_received_packet_; }
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h index 1bfacee..bc7245a 100644 --- a/quic/core/quic_connection.h +++ b/quic/core/quic_connection.h
@@ -1471,13 +1471,20 @@ // Timestamps used for timeouts. // The time of the first retransmittable packet that was sent after the most // recently received packet. - // TODO(fayang): Remove these two when deprecating - // quic_use_idle_network_detector. + // TODO(fayang): Remove time_of_first_packet_sent_after_receiving_ when + // deprecating quic_use_idle_network_detector. QuicTime time_of_first_packet_sent_after_receiving_; // The time that a packet is received for this connection. Initialized to // connection creation time. - // This is used for timeouts, and does not indicate the packet was processed. + // This does not indicate the packet was processed. QuicTime time_of_last_received_packet_; + // This gets set to time_of_last_received_packet_ when a packet gets + // decrypted. Please note, this is not necessarily the original receive time + // of this decrypt packet because connection can decryptable packet out of + // order. + // TODO(fayang): Remove time_of_last_decryptable_packet_ when + // deprecating quic_use_idle_network_detector. + QuicTime time_of_last_decryptable_packet_; // Sent packet manager which tracks the status of packets sent by this // connection and contains the send and receive algorithms to determine when @@ -1651,6 +1658,9 @@ const bool use_idle_network_detector_ = use_blackhole_detector_ && GetQuicReloadableFlag(quic_use_idle_network_detector); + + const bool extend_idle_time_on_decryptable_packets_ = + GetQuicReloadableFlag(quic_extend_idle_time_on_decryptable_packets); }; } // namespace quic
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc index edeff6d..1822d0c 100644 --- a/quic/core/quic_connection_test.cc +++ b/quic/core/quic_connection_test.cc
@@ -10634,6 +10634,48 @@ } } +TEST_P(QuicConnectionTest, DonotExtendIdleTimeOnUndecryptablePackets) { + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + QuicConfig config; + connection_.SetFromConfig(config); + // Subtract a second from the idle timeout on the client side. + QuicTime initial_deadline = + clock_.ApproximateNow() + + QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1); + EXPECT_EQ(initial_deadline, connection_.GetTimeoutAlarm()->deadline()); + + // Received an undecryptable packet. + clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); + const uint8_t tag = 0x07; + peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE, + std::make_unique<TaggingEncrypter>(tag)); + ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_FORWARD_SECURE); + if (GetQuicReloadableFlag(quic_extend_idle_time_on_decryptable_packets) || + !GetQuicReloadableFlag(quic_use_blackhole_detector)) { + // Verify deadline does not get extended. + EXPECT_EQ(initial_deadline, connection_.GetTimeoutAlarm()->deadline()); + } + if (GetQuicReloadableFlag(quic_extend_idle_time_on_decryptable_packets)) { + EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(1); + } else { + EXPECT_CALL(visitor_, OnConnectionClosed(_, _)).Times(0); + } + QuicTime::Delta delay = initial_deadline - clock_.ApproximateNow(); + clock_.AdvanceTime(delay); + if (GetQuicReloadableFlag(quic_extend_idle_time_on_decryptable_packets) || + !GetQuicReloadableFlag(quic_use_blackhole_detector)) { + connection_.GetTimeoutAlarm()->Fire(); + } + if (GetQuicReloadableFlag(quic_extend_idle_time_on_decryptable_packets)) { + // Verify connection gets closed. + EXPECT_FALSE(connection_.connected()); + } else { + // Verify the timeout alarm deadline is updated. + EXPECT_TRUE(connection_.connected()); + EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet()); + } +} + } // namespace } // namespace test } // namespace quic