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 3// found in the LICENSE file. 4// 5// Handles packets for connection_ids in time wait state by discarding the 6// packet and sending the clients a public reset packet with exponential 7// backoff. 8 9#ifndef NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_ 10#define NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_ 11 12#include <deque> 13 14#include "base/basictypes.h" 15#include "base/containers/hash_tables.h" 16#include "base/strings/string_piece.h" 17#include "net/base/linked_hash_map.h" 18#include "net/quic/quic_blocked_writer_interface.h" 19#include "net/quic/quic_framer.h" 20#include "net/quic/quic_packet_writer.h" 21#include "net/quic/quic_protocol.h" 22#include "net/tools/quic/quic_epoll_clock.h" 23 24namespace net { 25 26class EpollServer; 27 28namespace tools { 29 30class ConnectionIdCleanUpAlarm; 31class QuicServerSessionVisitor; 32 33namespace test { 34class QuicTimeWaitListManagerPeer; 35} // namespace test 36 37// Maintains a list of all connection_ids that have been recently closed. A 38// connection_id lives in this state for kTimeWaitPeriod. All packets received 39// for connection_ids in this state are handed over to the 40// QuicTimeWaitListManager by the QuicDispatcher. Decides whether to send a 41// public reset packet, a copy of the previously sent connection close packet, 42// or nothing to the client which sent a packet with the connection_id in time 43// wait state. After the connection_id expires its time wait period, a new 44// connection/session will be created if a packet is received for this 45// connection_id. 46class QuicTimeWaitListManager : public QuicBlockedWriterInterface { 47 public: 48 // writer - the entity that writes to the socket. (Owned by the dispatcher) 49 // visitor - the entity that manages blocked writers. (The dispatcher) 50 // epoll_server - used to run clean up alarms. (Owned by the dispatcher) 51 QuicTimeWaitListManager(QuicPacketWriter* writer, 52 QuicServerSessionVisitor* visitor, 53 EpollServer* epoll_server, 54 const QuicVersionVector& supported_versions); 55 virtual ~QuicTimeWaitListManager(); 56 57 // Adds the given connection_id to time wait state for kTimeWaitPeriod. 58 // Henceforth, any packet bearing this connection_id should not be processed 59 // while the connection_id remains in this list. If a non-NULL |close_packet| 60 // is provided, it is sent again when packets are received for added 61 // connection_ids. If NULL, a public reset packet is sent with the specified 62 // |version|. DCHECKs that connection_id is not already on the list. 63 void AddConnectionIdToTimeWait(QuicConnectionId connection_id, 64 QuicVersion version, 65 QuicEncryptedPacket* close_packet); // Owned. 66 67 // Returns true if the connection_id is in time wait state, false otherwise. 68 // Packets received for this connection_id should not lead to creation of new 69 // QuicSessions. 70 bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) const; 71 72 // Called when a packet is received for a connection_id that is in time wait 73 // state. Sends a public reset packet to the client which sent this 74 // connection_id. Sending of the public reset packet is throttled by using 75 // exponential back off. DCHECKs for the connection_id to be in time wait 76 // state. virtual to override in tests. 77 virtual void ProcessPacket(const IPEndPoint& server_address, 78 const IPEndPoint& client_address, 79 QuicConnectionId connection_id, 80 QuicPacketSequenceNumber sequence_number, 81 const QuicEncryptedPacket& packet); 82 83 // Called by the dispatcher when the underlying socket becomes writable again, 84 // since we might need to send pending public reset packets which we didn't 85 // send because the underlying socket was write blocked. 86 virtual void OnCanWrite() OVERRIDE; 87 88 // Used to delete connection_id entries that have outlived their time wait 89 // period. 90 void CleanUpOldConnectionIds(); 91 92 // Given a ConnectionId that exists in the time wait list, returns the 93 // QuicVersion associated with it. 94 QuicVersion GetQuicVersionFromConnectionId(QuicConnectionId connection_id); 95 96 protected: 97 virtual QuicEncryptedPacket* BuildPublicReset( 98 const QuicPublicResetPacket& packet); 99 100 private: 101 friend class test::QuicTimeWaitListManagerPeer; 102 103 // Internal structure to store pending public reset packets. 104 class QueuedPacket; 105 106 // Decides if a packet should be sent for this connection_id based on the 107 // number of received packets. 108 bool ShouldSendResponse(int received_packet_count); 109 110 // Creates a public reset packet and sends it or queues it to be sent later. 111 void SendPublicReset(const IPEndPoint& server_address, 112 const IPEndPoint& client_address, 113 QuicConnectionId connection_id, 114 QuicPacketSequenceNumber rejected_sequence_number); 115 116 // Either sends the packet and deletes it or makes pending_packets_queue_ the 117 // owner of the packet. 118 void SendOrQueuePacket(QueuedPacket* packet); 119 120 // Sends the packet out. Returns true if the packet was successfully consumed. 121 // If the writer got blocked and did not buffer the packet, we'll need to keep 122 // the packet and retry sending. In case of all other errors we drop the 123 // packet. 124 bool WriteToWire(QueuedPacket* packet); 125 126 // Register the alarm with the epoll server to wake up at appropriate time. 127 void SetConnectionIdCleanUpAlarm(); 128 129 // A map from a recently closed connection_id to the number of packets 130 // received after the termination of the connection bound to the 131 // connection_id. 132 struct ConnectionIdData { 133 ConnectionIdData(int num_packets_, 134 QuicVersion version_, 135 QuicTime time_added_, 136 QuicEncryptedPacket* close_packet) 137 : num_packets(num_packets_), 138 version(version_), 139 time_added(time_added_), 140 close_packet(close_packet) {} 141 int num_packets; 142 QuicVersion version; 143 QuicTime time_added; 144 QuicEncryptedPacket* close_packet; 145 }; 146 147 // linked_hash_map allows lookup by ConnectionId and traversal in add order. 148 typedef linked_hash_map<QuicConnectionId, ConnectionIdData> ConnectionIdMap; 149 ConnectionIdMap connection_id_map_; 150 151 // Pending public reset packets that need to be sent out to the client 152 // when we are given a chance to write by the dispatcher. 153 std::deque<QueuedPacket*> pending_packets_queue_; 154 155 // Used to schedule alarms to delete old connection_ids which have been in the 156 // list for too long. 157 EpollServer* epoll_server_; 158 159 // Time period for which connection_ids should remain in time wait state. 160 const QuicTime::Delta kTimeWaitPeriod_; 161 162 // Alarm registered with the epoll server to clean up connection_ids that have 163 // out lived their duration in time wait state. 164 scoped_ptr<ConnectionIdCleanUpAlarm> connection_id_clean_up_alarm_; 165 166 // Clock to efficiently measure approximate time from the epoll server. 167 QuicEpollClock clock_; 168 169 // Interface that writes given buffer to the socket. 170 QuicPacketWriter* writer_; 171 172 // Interface that manages blocked writers. 173 QuicServerSessionVisitor* visitor_; 174 175 DISALLOW_COPY_AND_ASSIGN(QuicTimeWaitListManager); 176}; 177 178} // namespace tools 179} // namespace net 180 181#endif // NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_ 182