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