Index: net/quic/quic_time_wait_list_manager.cc |
diff --git a/net/quic/quic_time_wait_list_manager.cc b/net/quic/quic_time_wait_list_manager.cc |
index 984d95faa7dd248f6b57751e379deab7ff5b0408..52ee2da0534acf54b2cf8ff27b2992f7c7641406 100644 |
--- a/net/quic/quic_time_wait_list_manager.cc |
+++ b/net/quic/quic_time_wait_list_manager.cc |
@@ -15,6 +15,7 @@ |
#include "net/quic/crypto/quic_encrypter.h" |
#include "net/quic/quic_clock.h" |
#include "net/quic/quic_connection_helper.h" |
+#include "net/quic/quic_flags.h" |
#include "net/quic/quic_framer.h" |
#include "net/quic/quic_protocol.h" |
#include "net/quic/quic_server_session.h" |
@@ -25,14 +26,6 @@ using std::make_pair; |
namespace net { |
-namespace { |
- |
-// Time period for which a given connection_id should live in the time-wait |
-// state. |
-int64 FLAGS_quic_time_wait_list_seconds = 5; |
- |
-} // namespace |
- |
// A very simple alarm that just informs the QuicTimeWaitListManager to clean |
// up old connection_ids. This alarm should be unregistered and deleted before |
// the QuicTimeWaitListManager is deleted. |
@@ -120,6 +113,11 @@ void QuicTimeWaitListManager::AddConnectionIdToTimeWait( |
delete it->second.close_packet; |
connection_id_map_.erase(it); |
} |
+ TrimTimeWaitListIfNeeded(); |
+ if (FLAGS_quic_limit_time_wait_list_size) { |
+ DCHECK_LT(num_connections(), |
+ static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections)); |
+ } |
ConnectionIdData data(num_packets, |
version, |
helper_->GetClock()->ApproximateNow(), |
@@ -272,21 +270,59 @@ void QuicTimeWaitListManager::SetConnectionIdCleanUpAlarm() { |
connection_id_clean_up_alarm_->Set(next_alarm_time); |
} |
+bool QuicTimeWaitListManager::MaybeExpireOldestConnection( |
+ QuicTime expiration_time) { |
+ if (connection_id_map_.empty()) { |
+ return false; |
+ } |
+ ConnectionIdMap::iterator it = connection_id_map_.begin(); |
+ QuicTime oldest_connection_id_time = it->second.time_added; |
+ if (oldest_connection_id_time > expiration_time) { |
+ // Too recent, don't retire. |
+ return false; |
+ } |
+ // This connection_id has lived its age, retire it now. |
+ const QuicConnectionId connection_id = it->first; |
+ delete it->second.close_packet; |
+ connection_id_map_.erase(it); |
+ visitor_->OnConnectionRemovedFromTimeWaitList(connection_id); |
+ return true; |
+} |
+ |
void QuicTimeWaitListManager::CleanUpOldConnectionIds() { |
QuicTime now = helper_->GetClock()->ApproximateNow(); |
- while (!connection_id_map_.empty()) { |
- ConnectionIdMap::iterator it = connection_id_map_.begin(); |
- QuicTime oldest_connection_id = it->second.time_added; |
- if (now.Subtract(oldest_connection_id) < kTimeWaitPeriod_) { |
- break; |
+ QuicTime expiration = now.Subtract(kTimeWaitPeriod_); |
+ if (FLAGS_quic_limit_time_wait_list_size) { |
+ while (MaybeExpireOldestConnection(expiration)) { |
+ } |
+ } else { |
+ while (!connection_id_map_.empty()) { |
+ ConnectionIdMap::iterator it = connection_id_map_.begin(); |
+ QuicTime oldest_connection_id = it->second.time_added; |
+ if (now.Subtract(oldest_connection_id) < kTimeWaitPeriod_) { |
+ break; |
+ } |
+ const QuicConnectionId connection_id = it->first; |
+ // This connection_id has lived its age, retire it now. |
+ delete it->second.close_packet; |
+ connection_id_map_.erase(it); |
+ visitor_->OnConnectionRemovedFromTimeWaitList(connection_id); |
} |
- const QuicConnectionId connection_id = it->first; |
- // This connection_id has lived its age, retire it now. |
- delete it->second.close_packet; |
- connection_id_map_.erase(it); |
- visitor_->OnConnectionRemovedFromTimeWaitList(connection_id); |
} |
+ |
SetConnectionIdCleanUpAlarm(); |
} |
+void QuicTimeWaitListManager::TrimTimeWaitListIfNeeded() { |
+ if (FLAGS_quic_limit_time_wait_list_size) { |
+ if (FLAGS_quic_time_wait_list_max_connections < 0) { |
+ return; |
+ } |
+ while (num_connections() >= |
+ static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections)) { |
+ MaybeExpireOldestConnection(QuicTime::Infinite()); |
+ } |
+ } |
+} |
+ |
} // namespace net |