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 |
deleted file mode 100644 |
index 0311913d44b1cf19d44c0d7e51df514864cd5456..0000000000000000000000000000000000000000 |
--- a/net/quic/quic_time_wait_list_manager.cc |
+++ /dev/null |
@@ -1,309 +0,0 @@ |
-// Copyright 2014 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "net/quic/quic_time_wait_list_manager.h" |
- |
-#include <errno.h> |
- |
-#include "base/containers/hash_tables.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "base/stl_util.h" |
-#include "net/base/ip_endpoint.h" |
-#include "net/quic/crypto/crypto_protocol.h" |
-#include "net/quic/crypto/quic_decrypter.h" |
-#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" |
-#include "net/quic/quic_utils.h" |
- |
-using base::StringPiece; |
- |
-namespace net { |
- |
-// 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. |
-class ConnectionIdCleanUpAlarm : public QuicAlarm::Delegate { |
- public: |
- explicit ConnectionIdCleanUpAlarm( |
- QuicTimeWaitListManager* time_wait_list_manager) |
- : time_wait_list_manager_(time_wait_list_manager) { |
- } |
- |
- QuicTime OnAlarm() override { |
- time_wait_list_manager_->CleanUpOldConnectionIds(); |
- // Let the time wait manager register the alarm at appropriate time. |
- return QuicTime::Zero(); |
- } |
- |
- private: |
- // Not owned. |
- QuicTimeWaitListManager* time_wait_list_manager_; |
-}; |
- |
-// This class stores pending public reset packets to be sent to clients. |
-// server_address - server address on which a packet what was received for |
-// a connection_id in time wait state. |
-// client_address - address of the client that sent that packet. Needed to send |
-// the public reset packet back to the client. |
-// packet - the pending public reset packet that is to be sent to the client. |
-// created instance takes the ownership of this packet. |
-class QuicTimeWaitListManager::QueuedPacket { |
- public: |
- QueuedPacket(const IPEndPoint& server_address, |
- const IPEndPoint& client_address, |
- QuicEncryptedPacket* packet) |
- : server_address_(server_address), |
- client_address_(client_address), |
- packet_(packet) { |
- } |
- |
- const IPEndPoint& server_address() const { return server_address_; } |
- const IPEndPoint& client_address() const { return client_address_; } |
- QuicEncryptedPacket* packet() { return packet_.get(); } |
- |
- private: |
- const IPEndPoint server_address_; |
- const IPEndPoint client_address_; |
- scoped_ptr<QuicEncryptedPacket> packet_; |
- |
- DISALLOW_COPY_AND_ASSIGN(QueuedPacket); |
-}; |
- |
-QuicTimeWaitListManager::QuicTimeWaitListManager( |
- QuicPacketWriter* writer, |
- QuicServerSessionVisitor* visitor, |
- QuicConnectionHelperInterface* helper, |
- const QuicVersionVector& supported_versions) |
- : helper_(helper), |
- time_wait_period_( |
- QuicTime::Delta::FromSeconds(FLAGS_quic_time_wait_list_seconds)), |
- connection_id_clean_up_alarm_( |
- helper_->CreateAlarm(new ConnectionIdCleanUpAlarm(this))), |
- writer_(writer), |
- visitor_(visitor) { |
- SetConnectionIdCleanUpAlarm(); |
-} |
- |
-QuicTimeWaitListManager::~QuicTimeWaitListManager() { |
- connection_id_clean_up_alarm_->Cancel(); |
- STLDeleteElements(&pending_packets_queue_); |
- for (ConnectionIdMap::iterator it = connection_id_map_.begin(); |
- it != connection_id_map_.end(); |
- ++it) { |
- delete it->second.close_packet; |
- } |
-} |
- |
-void QuicTimeWaitListManager::AddConnectionIdToTimeWait( |
- QuicConnectionId connection_id, |
- QuicVersion version, |
- QuicEncryptedPacket* close_packet) { |
- int num_packets = 0; |
- ConnectionIdMap::iterator it = connection_id_map_.find(connection_id); |
- const bool new_connection_id = it == connection_id_map_.end(); |
- if (!new_connection_id) { // Replace record if it is reinserted. |
- num_packets = it->second.num_packets; |
- delete it->second.close_packet; |
- connection_id_map_.erase(it); |
- } |
- TrimTimeWaitListIfNeeded(); |
- DCHECK_LT(num_connections(), |
- static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections)); |
- ConnectionIdData data(num_packets, |
- version, |
- helper_->GetClock()->ApproximateNow(), |
- close_packet); |
- connection_id_map_.insert(std::make_pair(connection_id, data)); |
- if (new_connection_id) { |
- visitor_->OnConnectionAddedToTimeWaitList(connection_id); |
- } |
-} |
- |
-bool QuicTimeWaitListManager::IsConnectionIdInTimeWait( |
- QuicConnectionId connection_id) const { |
- return ContainsKey(connection_id_map_, connection_id); |
-} |
- |
-QuicVersion QuicTimeWaitListManager::GetQuicVersionFromConnectionId( |
- QuicConnectionId connection_id) { |
- ConnectionIdMap::iterator it = connection_id_map_.find(connection_id); |
- DCHECK(it != connection_id_map_.end()); |
- return (it->second).version; |
-} |
- |
-void QuicTimeWaitListManager::OnCanWrite() { |
- while (!pending_packets_queue_.empty()) { |
- QueuedPacket* queued_packet = pending_packets_queue_.front(); |
- if (!WriteToWire(queued_packet)) { |
- return; |
- } |
- pending_packets_queue_.pop_front(); |
- delete queued_packet; |
- } |
-} |
- |
-void QuicTimeWaitListManager::ProcessPacket( |
- const IPEndPoint& server_address, |
- const IPEndPoint& client_address, |
- QuicConnectionId connection_id, |
- QuicPacketSequenceNumber sequence_number, |
- const QuicEncryptedPacket& /*packet*/) { |
- DCHECK(IsConnectionIdInTimeWait(connection_id)); |
- DVLOG(1) << "Processing " << connection_id << " in time wait state."; |
- // TODO(satyamshekhar): Think about handling packets from different client |
- // addresses. |
- ConnectionIdMap::iterator it = connection_id_map_.find(connection_id); |
- DCHECK(it != connection_id_map_.end()); |
- // Increment the received packet count. |
- ++((it->second).num_packets); |
- if (!ShouldSendResponse((it->second).num_packets)) { |
- return; |
- } |
- if (it->second.close_packet) { |
- QueuedPacket* queued_packet = |
- new QueuedPacket(server_address, |
- client_address, |
- it->second.close_packet->Clone()); |
- // Takes ownership of the packet. |
- SendOrQueuePacket(queued_packet); |
- } else { |
- SendPublicReset(server_address, |
- client_address, |
- connection_id, |
- sequence_number); |
- } |
-} |
- |
-// Returns true if the number of packets received for this connection_id is a |
-// power of 2 to throttle the number of public reset packets we send to a |
-// client. |
-bool QuicTimeWaitListManager::ShouldSendResponse(int received_packet_count) { |
- return (received_packet_count & (received_packet_count - 1)) == 0; |
-} |
- |
-void QuicTimeWaitListManager::SendPublicReset( |
- const IPEndPoint& server_address, |
- const IPEndPoint& client_address, |
- QuicConnectionId connection_id, |
- QuicPacketSequenceNumber rejected_sequence_number) { |
- QuicPublicResetPacket packet; |
- packet.public_header.connection_id = connection_id; |
- packet.public_header.reset_flag = true; |
- packet.public_header.version_flag = false; |
- packet.rejected_sequence_number = rejected_sequence_number; |
- // TODO(satyamshekhar): generate a valid nonce for this connection_id. |
- packet.nonce_proof = 1010101; |
- packet.client_address = client_address; |
- QueuedPacket* queued_packet = new QueuedPacket( |
- server_address, |
- client_address, |
- BuildPublicReset(packet)); |
- // Takes ownership of the packet. |
- SendOrQueuePacket(queued_packet); |
-} |
- |
-QuicEncryptedPacket* QuicTimeWaitListManager::BuildPublicReset( |
- const QuicPublicResetPacket& packet) { |
- return QuicFramer::BuildPublicResetPacket(packet); |
-} |
- |
-// Either sends the packet and deletes it or makes pending queue the |
-// owner of the packet. |
-void QuicTimeWaitListManager::SendOrQueuePacket(QueuedPacket* packet) { |
- if (WriteToWire(packet)) { |
- delete packet; |
- } else { |
- // pending_packets_queue takes the ownership of the queued packet. |
- pending_packets_queue_.push_back(packet); |
- } |
-} |
- |
-bool QuicTimeWaitListManager::WriteToWire(QueuedPacket* queued_packet) { |
- if (writer_->IsWriteBlocked()) { |
- visitor_->OnWriteBlocked(this); |
- return false; |
- } |
- WriteResult result = writer_->WritePacket( |
- queued_packet->packet()->data(), |
- queued_packet->packet()->length(), |
- queued_packet->server_address().address(), |
- queued_packet->client_address()); |
- if (result.status == WRITE_STATUS_BLOCKED) { |
- // If blocked and unbuffered, return false to retry sending. |
- DCHECK(writer_->IsWriteBlocked()); |
- visitor_->OnWriteBlocked(this); |
- return writer_->IsWriteBlockedDataBuffered(); |
- } else if (result.status == WRITE_STATUS_ERROR) { |
- LOG(WARNING) << "Received unknown error while sending reset packet to " |
- << queued_packet->client_address().ToString() << ": " |
- << strerror(result.error_code); |
- } |
- return true; |
-} |
- |
-void QuicTimeWaitListManager::SetConnectionIdCleanUpAlarm() { |
- connection_id_clean_up_alarm_->Cancel(); |
- QuicTime now = helper_->GetClock()->ApproximateNow(); |
- QuicTime next_alarm_time = now; |
- if (!connection_id_map_.empty()) { |
- QuicTime oldest_connection_id = |
- connection_id_map_.begin()->second.time_added; |
- if (now.Subtract(oldest_connection_id) < time_wait_period_) { |
- next_alarm_time = oldest_connection_id.Add(time_wait_period_); |
- } else { |
- LOG(ERROR) << "ConnectionId lingered for longer than kTimeWaitPeriod"; |
- } |
- } else { |
- // No connection_ids added so none will expire before time_wait_period_. |
- next_alarm_time = now.Add(time_wait_period_); |
- } |
- |
- 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(); |
- QuicTime expiration = now.Subtract(time_wait_period_); |
- |
- while (MaybeExpireOldestConnection(expiration)) { |
- } |
- |
- SetConnectionIdCleanUpAlarm(); |
-} |
- |
-void QuicTimeWaitListManager::TrimTimeWaitListIfNeeded() { |
- 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 |