gfe-relnote: In QUIC, fix a bug where setting FLAGS_quic_time_wait_list_max_connections to 0 causes infinite loop. Not protected. PiperOrigin-RevId: 259040672 Change-Id: I00f2daf6443852996ae0a4d7c25ae4738a900ab2
diff --git a/quic/core/quic_time_wait_list_manager.cc b/quic/core/quic_time_wait_list_manager.cc index 8bcb162..cb29a40 100644 --- a/quic/core/quic_time_wait_list_manager.cc +++ b/quic/core/quic_time_wait_list_manager.cc
@@ -83,7 +83,8 @@ TrimTimeWaitListIfNeeded(); int64_t max_connections = GetQuicFlag(FLAGS_quic_time_wait_list_max_connections); - DCHECK_LT(num_connections(), static_cast<size_t>(max_connections)); + DCHECK(connection_id_map_.empty() || + num_connections() < static_cast<size_t>(max_connections)); ConnectionIdData data(num_packets, ietf_quic, clock_->ApproximateNow(), action); if (termination_packets != nullptr) { @@ -377,7 +378,8 @@ if (kMaxConnections < 0) { return; } - while (num_connections() >= static_cast<size_t>(kMaxConnections)) { + while (!connection_id_map_.empty() && + num_connections() >= static_cast<size_t>(kMaxConnections)) { MaybeExpireOldestConnection(QuicTime::Infinite()); } }
diff --git a/quic/core/quic_time_wait_list_manager_test.cc b/quic/core/quic_time_wait_list_manager_test.cc index 3fdd454..0d9e32a 100644 --- a/quic/core/quic_time_wait_list_manager_test.cc +++ b/quic/core/quic_time_wait_list_manager_test.cc
@@ -579,6 +579,27 @@ } } +TEST_F(QuicTimeWaitListManagerTest, ZeroMaxConnections) { + // Basically, shut off time-based eviction. + SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000000000); + // Keep time wait list empty. + SetQuicFlag(FLAGS_quic_time_wait_list_max_connections, 0); + + uint64_t current_conn_id = 0; + // Add exactly the maximum number of connections + for (int64_t i = 0; i < 10; ++i) { + ++current_conn_id; + QuicConnectionId current_connection_id = TestConnectionId(current_conn_id); + EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id)); + EXPECT_CALL(visitor_, + OnConnectionAddedToTimeWaitList(current_connection_id)); + AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING); + // Verify time wait list always has 1 connection. + EXPECT_EQ(1u, time_wait_list_manager_.num_connections()); + EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id)); + } +} + // Regression test for b/116200989. TEST_F(QuicTimeWaitListManagerTest, SendStatelessResetInResponseToShortHeaders) {