Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: net/tools/quic/quic_time_wait_list_manager.cc

Issue 999353005: Land Recent QUIC Changes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: wrap Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_flags.h"
18 #include "net/quic/quic_framer.h" 18 #include "net/quic/quic_framer.h"
19 #include "net/quic/quic_protocol.h" 19 #include "net/quic/quic_protocol.h"
20 #include "net/quic/quic_utils.h" 20 #include "net/quic/quic_utils.h"
21 #include "net/tools/epoll_server/epoll_server.h"
22 #include "net/tools/quic/quic_server_session.h" 21 #include "net/tools/quic/quic_server_session.h"
23 22
24 using base::StringPiece; 23 using base::StringPiece;
25 24
26 namespace net { 25 namespace net {
27 namespace tools { 26 namespace tools {
28 27
29 // TODO(rtenneti): Remove the duplicated code in this file. Share code with 28 // TODO(rtenneti): Remove the duplicated code in this file. Share code with
30 // "net/quic/quic_time_wait_list_manager.cc" 29 // "net/quic/quic_time_wait_list_manager.cc"
31 30
32 // A very simple alarm that just informs the QuicTimeWaitListManager to clean 31 // A very simple alarm that just informs the QuicTimeWaitListManager to clean
33 // up old connection_ids. This alarm should be unregistered and deleted before 32 // up old connection_ids. This alarm should be cancelled and deleted before
34 // the QuicTimeWaitListManager is deleted. 33 // the QuicTimeWaitListManager is deleted.
35 class ConnectionIdCleanUpAlarm : public EpollAlarm { 34 class ConnectionIdCleanUpAlarm : public QuicAlarm::Delegate {
36 public: 35 public:
37 explicit ConnectionIdCleanUpAlarm( 36 explicit ConnectionIdCleanUpAlarm(
38 QuicTimeWaitListManager* time_wait_list_manager) 37 QuicTimeWaitListManager* time_wait_list_manager)
39 : time_wait_list_manager_(time_wait_list_manager) { 38 : time_wait_list_manager_(time_wait_list_manager) {
40 } 39 }
41 40
42 int64 OnAlarm() override { 41 QuicTime OnAlarm() override {
43 EpollAlarm::OnAlarm();
44 time_wait_list_manager_->CleanUpOldConnectionIds(); 42 time_wait_list_manager_->CleanUpOldConnectionIds();
45 // Let the time wait manager register the alarm at appropriate time. 43 // Let the time wait manager register the alarm at appropriate time.
46 return 0; 44 return QuicTime::Zero();
47 } 45 }
48 46
49 private: 47 private:
50 // Not owned. 48 // Not owned.
51 QuicTimeWaitListManager* time_wait_list_manager_; 49 QuicTimeWaitListManager* time_wait_list_manager_;
50
51 DISALLOW_COPY_AND_ASSIGN(ConnectionIdCleanUpAlarm);
52 }; 52 };
53 53
54
54 // This class stores pending public reset packets to be sent to clients. 55 // This class stores pending public reset packets to be sent to clients.
55 // server_address - server address on which a packet what was received for 56 // server_address - server address on which a packet what was received for
56 // a connection_id in time wait state. 57 // a connection_id in time wait state.
57 // client_address - address of the client that sent that packet. Needed to send 58 // client_address - address of the client that sent that packet. Needed to send
58 // the public reset packet back to the client. 59 // the public reset packet back to the client.
59 // packet - the pending public reset packet that is to be sent to the client. 60 // packet - the pending public reset packet that is to be sent to the client.
60 // created instance takes the ownership of this packet. 61 // created instance takes the ownership of this packet.
61 class QuicTimeWaitListManager::QueuedPacket { 62 class QuicTimeWaitListManager::QueuedPacket {
62 public: 63 public:
63 QueuedPacket(const IPEndPoint& server_address, 64 QueuedPacket(const IPEndPoint& server_address,
(...skipping 12 matching lines...) Expand all
76 const IPEndPoint server_address_; 77 const IPEndPoint server_address_;
77 const IPEndPoint client_address_; 78 const IPEndPoint client_address_;
78 scoped_ptr<QuicEncryptedPacket> packet_; 79 scoped_ptr<QuicEncryptedPacket> packet_;
79 80
80 DISALLOW_COPY_AND_ASSIGN(QueuedPacket); 81 DISALLOW_COPY_AND_ASSIGN(QueuedPacket);
81 }; 82 };
82 83
83 QuicTimeWaitListManager::QuicTimeWaitListManager( 84 QuicTimeWaitListManager::QuicTimeWaitListManager(
84 QuicPacketWriter* writer, 85 QuicPacketWriter* writer,
85 QuicServerSessionVisitor* visitor, 86 QuicServerSessionVisitor* visitor,
86 EpollServer* epoll_server, 87 QuicConnectionHelperInterface* helper,
87 const QuicVersionVector& supported_versions) 88 const QuicVersionVector& supported_versions)
88 : epoll_server_(epoll_server), 89 : time_wait_period_(
89 kTimeWaitPeriod_(
90 QuicTime::Delta::FromSeconds(FLAGS_quic_time_wait_list_seconds)), 90 QuicTime::Delta::FromSeconds(FLAGS_quic_time_wait_list_seconds)),
91 connection_id_clean_up_alarm_(new ConnectionIdCleanUpAlarm(this)), 91 connection_id_clean_up_alarm_(
92 clock_(epoll_server_), 92 helper->CreateAlarm(new ConnectionIdCleanUpAlarm(this))),
93 clock_(helper->GetClock()),
93 writer_(writer), 94 writer_(writer),
94 visitor_(visitor) { 95 visitor_(visitor) {
95 SetConnectionIdCleanUpAlarm(); 96 SetConnectionIdCleanUpAlarm();
96 } 97 }
97 98
98 QuicTimeWaitListManager::~QuicTimeWaitListManager() { 99 QuicTimeWaitListManager::~QuicTimeWaitListManager() {
99 connection_id_clean_up_alarm_->UnregisterIfRegistered(); 100 connection_id_clean_up_alarm_->Cancel();
100 STLDeleteElements(&pending_packets_queue_); 101 STLDeleteElements(&pending_packets_queue_);
101 for (ConnectionIdMap::iterator it = connection_id_map_.begin(); 102 for (ConnectionIdMap::iterator it = connection_id_map_.begin();
102 it != connection_id_map_.end(); 103 it != connection_id_map_.end();
103 ++it) { 104 ++it) {
104 delete it->second.close_packet; 105 delete it->second.close_packet;
105 } 106 }
106 } 107 }
107 108
108 void QuicTimeWaitListManager::AddConnectionIdToTimeWait( 109 void QuicTimeWaitListManager::AddConnectionIdToTimeWait(
109 QuicConnectionId connection_id, 110 QuicConnectionId connection_id,
110 QuicVersion version, 111 QuicVersion version,
111 QuicEncryptedPacket* close_packet) { 112 QuicEncryptedPacket* close_packet) {
112 int num_packets = 0; 113 int num_packets = 0;
113 ConnectionIdMap::iterator it = connection_id_map_.find(connection_id); 114 ConnectionIdMap::iterator it = connection_id_map_.find(connection_id);
114 const bool new_connection_id = it == connection_id_map_.end(); 115 const bool new_connection_id = it == connection_id_map_.end();
115 if (!new_connection_id) { // Replace record if it is reinserted. 116 if (!new_connection_id) { // Replace record if it is reinserted.
116 num_packets = it->second.num_packets; 117 num_packets = it->second.num_packets;
117 delete it->second.close_packet; 118 delete it->second.close_packet;
118 connection_id_map_.erase(it); 119 connection_id_map_.erase(it);
119 } 120 }
120 TrimTimeWaitListIfNeeded(); 121 TrimTimeWaitListIfNeeded();
121 DCHECK_LT(num_connections(), 122 DCHECK_LT(num_connections(),
122 static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections)); 123 static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections));
123 ConnectionIdData data(num_packets, 124 ConnectionIdData data(num_packets,
124 version, 125 version,
125 clock_.ApproximateNow(), 126 clock_->ApproximateNow(),
126 close_packet); 127 close_packet);
127 connection_id_map_.insert(std::make_pair(connection_id, data)); 128 connection_id_map_.insert(std::make_pair(connection_id, data));
128 if (new_connection_id) { 129 if (new_connection_id) {
129 visitor_->OnConnectionAddedToTimeWaitList(connection_id); 130 visitor_->OnConnectionAddedToTimeWaitList(connection_id);
130 } 131 }
131 } 132 }
132 133
133 bool QuicTimeWaitListManager::IsConnectionIdInTimeWait( 134 bool QuicTimeWaitListManager::IsConnectionIdInTimeWait(
134 QuicConnectionId connection_id) const { 135 QuicConnectionId connection_id) const {
135 return ContainsKey(connection_id_map_, connection_id); 136 return ContainsKey(connection_id_map_, connection_id);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 return writer_->IsWriteBlockedDataBuffered(); 247 return writer_->IsWriteBlockedDataBuffered();
247 } else if (result.status == WRITE_STATUS_ERROR) { 248 } else if (result.status == WRITE_STATUS_ERROR) {
248 LOG(WARNING) << "Received unknown error while sending reset packet to " 249 LOG(WARNING) << "Received unknown error while sending reset packet to "
249 << queued_packet->client_address().ToString() << ": " 250 << queued_packet->client_address().ToString() << ": "
250 << strerror(result.error_code); 251 << strerror(result.error_code);
251 } 252 }
252 return true; 253 return true;
253 } 254 }
254 255
255 void QuicTimeWaitListManager::SetConnectionIdCleanUpAlarm() { 256 void QuicTimeWaitListManager::SetConnectionIdCleanUpAlarm() {
256 connection_id_clean_up_alarm_->UnregisterIfRegistered(); 257 connection_id_clean_up_alarm_->Cancel();
257 int64 next_alarm_interval; 258 QuicTime::Delta next_alarm_interval = QuicTime::Delta::Zero();
258 if (!connection_id_map_.empty()) { 259 if (!connection_id_map_.empty()) {
259 QuicTime oldest_connection_id = 260 QuicTime oldest_connection_id =
260 connection_id_map_.begin()->second.time_added; 261 connection_id_map_.begin()->second.time_added;
261 QuicTime now = clock_.ApproximateNow(); 262 QuicTime now = clock_->ApproximateNow();
262 if (now.Subtract(oldest_connection_id) < kTimeWaitPeriod_) { 263 if (now.Subtract(oldest_connection_id) < time_wait_period_) {
263 next_alarm_interval = oldest_connection_id.Add(kTimeWaitPeriod_) 264 next_alarm_interval = oldest_connection_id.Add(time_wait_period_)
264 .Subtract(now) 265 .Subtract(now);
265 .ToMicroseconds();
266 } else { 266 } else {
267 LOG(ERROR) << "ConnectionId lingered for longer than kTimeWaitPeriod"; 267 LOG(ERROR) << "ConnectionId lingered for longer than time_wait_period_";
268 next_alarm_interval = 0;
269 } 268 }
270 } else { 269 } else {
271 // No connection_ids added so none will expire before kTimeWaitPeriod_. 270 // No connection_ids added so none will expire before time_wait_period_.
272 next_alarm_interval = kTimeWaitPeriod_.ToMicroseconds(); 271 next_alarm_interval = time_wait_period_;
273 } 272 }
274 273
275 epoll_server_->RegisterAlarmApproximateDelta( 274 connection_id_clean_up_alarm_->Set(
276 next_alarm_interval, connection_id_clean_up_alarm_.get()); 275 clock_->ApproximateNow().Add(next_alarm_interval));
277 } 276 }
278 277
279 bool QuicTimeWaitListManager::MaybeExpireOldestConnection( 278 bool QuicTimeWaitListManager::MaybeExpireOldestConnection(
280 QuicTime expiration_time) { 279 QuicTime expiration_time) {
281 if (connection_id_map_.empty()) { 280 if (connection_id_map_.empty()) {
282 return false; 281 return false;
283 } 282 }
284 ConnectionIdMap::iterator it = connection_id_map_.begin(); 283 ConnectionIdMap::iterator it = connection_id_map_.begin();
285 QuicTime oldest_connection_id_time = it->second.time_added; 284 QuicTime oldest_connection_id_time = it->second.time_added;
286 if (oldest_connection_id_time > expiration_time) { 285 if (oldest_connection_id_time > expiration_time) {
287 // Too recent, don't retire. 286 // Too recent, don't retire.
288 return false; 287 return false;
289 } 288 }
290 // This connection_id has lived its age, retire it now. 289 // This connection_id has lived its age, retire it now.
291 const QuicConnectionId connection_id = it->first; 290 const QuicConnectionId connection_id = it->first;
292 delete it->second.close_packet; 291 delete it->second.close_packet;
293 connection_id_map_.erase(it); 292 connection_id_map_.erase(it);
294 visitor_->OnConnectionRemovedFromTimeWaitList(connection_id); 293 visitor_->OnConnectionRemovedFromTimeWaitList(connection_id);
295 return true; 294 return true;
296 } 295 }
297 296
298 void QuicTimeWaitListManager::CleanUpOldConnectionIds() { 297 void QuicTimeWaitListManager::CleanUpOldConnectionIds() {
299 QuicTime now = clock_.ApproximateNow(); 298 QuicTime now = clock_->ApproximateNow();
300 QuicTime expiration = now.Subtract(kTimeWaitPeriod_); 299 QuicTime expiration = now.Subtract(time_wait_period_);
301 300
302 while (MaybeExpireOldestConnection(expiration)) { 301 while (MaybeExpireOldestConnection(expiration)) {
303 } 302 }
304 303
305 SetConnectionIdCleanUpAlarm(); 304 SetConnectionIdCleanUpAlarm();
306 } 305 }
307 306
308 void QuicTimeWaitListManager::TrimTimeWaitListIfNeeded() { 307 void QuicTimeWaitListManager::TrimTimeWaitListIfNeeded() {
309 if (FLAGS_quic_time_wait_list_max_connections < 0) { 308 if (FLAGS_quic_time_wait_list_max_connections < 0) {
310 return; 309 return;
311 } 310 }
312 while (num_connections() >= 311 while (num_connections() >=
313 static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections)) { 312 static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections)) {
314 MaybeExpireOldestConnection(QuicTime::Infinite()); 313 MaybeExpireOldestConnection(QuicTime::Infinite());
315 } 314 }
316 } 315 }
317 316
318 } // namespace tools 317 } // namespace tools
319 } // namespace net 318 } // namespace net
OLDNEW
« no previous file with comments | « net/tools/quic/quic_time_wait_list_manager.h ('k') | net/tools/quic/quic_time_wait_list_manager_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698