| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/tools/quic/quic_time_wait_list_manager.h" | 5 #include "net/tools/quic/quic_time_wait_list_manager.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 | 8 |
| 9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 12 #include "net/base/ip_endpoint.h" | 12 #include "net/base/ip_endpoint.h" |
| 13 #include "net/quic/crypto/crypto_protocol.h" | 13 #include "net/quic/crypto/crypto_protocol.h" |
| 14 #include "net/quic/crypto/quic_decrypter.h" | 14 #include "net/quic/crypto/quic_decrypter.h" |
| 15 #include "net/quic/crypto/quic_encrypter.h" | 15 #include "net/quic/crypto/quic_encrypter.h" |
| 16 #include "net/quic/quic_clock.h" | 16 #include "net/quic/quic_clock.h" |
| 17 #include "net/quic/quic_flags.h" |
| 17 #include "net/quic/quic_framer.h" | 18 #include "net/quic/quic_framer.h" |
| 18 #include "net/quic/quic_protocol.h" | 19 #include "net/quic/quic_protocol.h" |
| 19 #include "net/quic/quic_utils.h" | 20 #include "net/quic/quic_utils.h" |
| 20 #include "net/tools/epoll_server/epoll_server.h" | 21 #include "net/tools/epoll_server/epoll_server.h" |
| 21 #include "net/tools/quic/quic_server_session.h" | 22 #include "net/tools/quic/quic_server_session.h" |
| 22 | 23 |
| 23 using base::StringPiece; | 24 using base::StringPiece; |
| 24 using std::make_pair; | 25 using std::make_pair; |
| 25 | 26 |
| 26 namespace net { | 27 namespace net { |
| 27 namespace tools { | 28 namespace tools { |
| 28 | 29 |
| 29 namespace { | 30 // TODO(rtenneti): Remove the duplicated code in this file. Share code with |
| 30 | 31 // "net/quic/quic_time_wait_list_manager.cc" |
| 31 // Time period for which a given connection_id should live in the time-wait | |
| 32 // state. | |
| 33 int64 FLAGS_quic_time_wait_list_seconds = 5; | |
| 34 | |
| 35 } // namespace | |
| 36 | 32 |
| 37 // A very simple alarm that just informs the QuicTimeWaitListManager to clean | 33 // A very simple alarm that just informs the QuicTimeWaitListManager to clean |
| 38 // up old connection_ids. This alarm should be unregistered and deleted before | 34 // up old connection_ids. This alarm should be unregistered and deleted before |
| 39 // the QuicTimeWaitListManager is deleted. | 35 // the QuicTimeWaitListManager is deleted. |
| 40 class ConnectionIdCleanUpAlarm : public EpollAlarm { | 36 class ConnectionIdCleanUpAlarm : public EpollAlarm { |
| 41 public: | 37 public: |
| 42 explicit ConnectionIdCleanUpAlarm( | 38 explicit ConnectionIdCleanUpAlarm( |
| 43 QuicTimeWaitListManager* time_wait_list_manager) | 39 QuicTimeWaitListManager* time_wait_list_manager) |
| 44 : time_wait_list_manager_(time_wait_list_manager) { | 40 : time_wait_list_manager_(time_wait_list_manager) { |
| 45 } | 41 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 QuicVersion version, | 111 QuicVersion version, |
| 116 QuicEncryptedPacket* close_packet) { | 112 QuicEncryptedPacket* close_packet) { |
| 117 int num_packets = 0; | 113 int num_packets = 0; |
| 118 ConnectionIdMap::iterator it = connection_id_map_.find(connection_id); | 114 ConnectionIdMap::iterator it = connection_id_map_.find(connection_id); |
| 119 const bool new_connection_id = it == connection_id_map_.end(); | 115 const bool new_connection_id = it == connection_id_map_.end(); |
| 120 if (!new_connection_id) { // Replace record if it is reinserted. | 116 if (!new_connection_id) { // Replace record if it is reinserted. |
| 121 num_packets = it->second.num_packets; | 117 num_packets = it->second.num_packets; |
| 122 delete it->second.close_packet; | 118 delete it->second.close_packet; |
| 123 connection_id_map_.erase(it); | 119 connection_id_map_.erase(it); |
| 124 } | 120 } |
| 121 TrimTimeWaitListIfNeeded(); |
| 122 if (FLAGS_quic_limit_time_wait_list_size) { |
| 123 DCHECK_LT(num_connections(), |
| 124 static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections)); |
| 125 } |
| 125 ConnectionIdData data(num_packets, | 126 ConnectionIdData data(num_packets, |
| 126 version, | 127 version, |
| 127 clock_.ApproximateNow(), | 128 clock_.ApproximateNow(), |
| 128 close_packet); | 129 close_packet); |
| 129 connection_id_map_.insert(make_pair(connection_id, data)); | 130 connection_id_map_.insert(make_pair(connection_id, data)); |
| 130 if (new_connection_id) { | 131 if (new_connection_id) { |
| 131 visitor_->OnConnectionAddedToTimeWaitList(connection_id); | 132 visitor_->OnConnectionAddedToTimeWaitList(connection_id); |
| 132 } | 133 } |
| 133 } | 134 } |
| 134 | 135 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 } | 272 } |
| 272 } else { | 273 } else { |
| 273 // No connection_ids added so none will expire before kTimeWaitPeriod_. | 274 // No connection_ids added so none will expire before kTimeWaitPeriod_. |
| 274 next_alarm_interval = kTimeWaitPeriod_.ToMicroseconds(); | 275 next_alarm_interval = kTimeWaitPeriod_.ToMicroseconds(); |
| 275 } | 276 } |
| 276 | 277 |
| 277 epoll_server_->RegisterAlarmApproximateDelta( | 278 epoll_server_->RegisterAlarmApproximateDelta( |
| 278 next_alarm_interval, connection_id_clean_up_alarm_.get()); | 279 next_alarm_interval, connection_id_clean_up_alarm_.get()); |
| 279 } | 280 } |
| 280 | 281 |
| 282 bool QuicTimeWaitListManager::MaybeExpireOldestConnection( |
| 283 QuicTime expiration_time) { |
| 284 if (connection_id_map_.empty()) { |
| 285 return false; |
| 286 } |
| 287 ConnectionIdMap::iterator it = connection_id_map_.begin(); |
| 288 QuicTime oldest_connection_id_time = it->second.time_added; |
| 289 if (oldest_connection_id_time > expiration_time) { |
| 290 // Too recent, don't retire. |
| 291 return false; |
| 292 } |
| 293 // This connection_id has lived its age, retire it now. |
| 294 const QuicConnectionId connection_id = it->first; |
| 295 delete it->second.close_packet; |
| 296 connection_id_map_.erase(it); |
| 297 visitor_->OnConnectionRemovedFromTimeWaitList(connection_id); |
| 298 return true; |
| 299 } |
| 300 |
| 281 void QuicTimeWaitListManager::CleanUpOldConnectionIds() { | 301 void QuicTimeWaitListManager::CleanUpOldConnectionIds() { |
| 282 QuicTime now = clock_.ApproximateNow(); | 302 QuicTime now = clock_.ApproximateNow(); |
| 283 while (!connection_id_map_.empty()) { | 303 QuicTime expiration = now.Subtract(kTimeWaitPeriod_); |
| 284 ConnectionIdMap::iterator it = connection_id_map_.begin(); | 304 if (FLAGS_quic_limit_time_wait_list_size) { |
| 285 QuicTime oldest_connection_id = it->second.time_added; | 305 while (MaybeExpireOldestConnection(expiration)) { |
| 286 if (now.Subtract(oldest_connection_id) < kTimeWaitPeriod_) { | |
| 287 break; | |
| 288 } | 306 } |
| 289 const QuicConnectionId connection_id = it->first; | 307 } else { |
| 290 // This connection_id has lived its age, retire it now. | 308 while (!connection_id_map_.empty()) { |
| 291 delete it->second.close_packet; | 309 ConnectionIdMap::iterator it = connection_id_map_.begin(); |
| 292 connection_id_map_.erase(it); | 310 QuicTime oldest_connection_id = it->second.time_added; |
| 293 visitor_->OnConnectionRemovedFromTimeWaitList(connection_id); | 311 if (now.Subtract(oldest_connection_id) < kTimeWaitPeriod_) { |
| 312 break; |
| 313 } |
| 314 const QuicConnectionId connection_id = it->first; |
| 315 // This connection_id has lived its age, retire it now. |
| 316 delete it->second.close_packet; |
| 317 connection_id_map_.erase(it); |
| 318 visitor_->OnConnectionRemovedFromTimeWaitList(connection_id); |
| 319 } |
| 294 } | 320 } |
| 321 |
| 295 SetConnectionIdCleanUpAlarm(); | 322 SetConnectionIdCleanUpAlarm(); |
| 296 } | 323 } |
| 297 | 324 |
| 325 void QuicTimeWaitListManager::TrimTimeWaitListIfNeeded() { |
| 326 if (FLAGS_quic_limit_time_wait_list_size) { |
| 327 if (FLAGS_quic_time_wait_list_max_connections < 0) { |
| 328 return; |
| 329 } |
| 330 while (num_connections() >= |
| 331 static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections)) { |
| 332 MaybeExpireOldestConnection(QuicTime::Infinite()); |
| 333 } |
| 334 } |
| 335 } |
| 336 |
| 298 } // namespace tools | 337 } // namespace tools |
| 299 } // namespace net | 338 } // namespace net |
| OLD | NEW |