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