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 guids in time wait state by discarding the packet and 6 // sending the clients a public reset packet with exponential backoff. 7 8 #ifndef NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_ 9 #define NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_ 10 11 #include <deque> 12 13 #include "base/containers/hash_tables.h" 14 #include "base/strings/string_piece.h" 15 #include "net/quic/quic_blocked_writer_interface.h" 16 #include "net/quic/quic_framer.h" 17 #include "net/quic/quic_packet_writer.h" 18 #include "net/quic/quic_protocol.h" 19 #include "net/tools/epoll_server/epoll_server.h" 20 #include "net/tools/quic/quic_epoll_clock.h" 21 22 namespace net { 23 namespace tools { 24 25 class GuidCleanUpAlarm; 26 27 namespace test { 28 class QuicTimeWaitListManagerPeer; 29 } // namespace test 30 31 // Maintains a list of all guids that have been recently closed. A guid lives in 32 // this state for kTimeWaitPeriod. All packets received for guids in this state 33 // are handed over to the QuicTimeWaitListManager by the QuicDispatcher. 34 // Decides whether to send a public reset packet, a copy of the previously sent 35 // connection close packet, or nothing to the client which sent a packet 36 // with the guid in time wait state. After the guid expires its time wait 37 // period, a new connection/session will be created if a packet is received 38 // for this guid. 39 class QuicTimeWaitListManager : public QuicBlockedWriterInterface, 40 public QuicFramerVisitorInterface { 41 public: 42 // writer - the entity that writes to the socket. (Owned by the dispatcher) 43 // epoll_server - used to run clean up alarms. (Owned by the dispatcher) 44 QuicTimeWaitListManager(QuicPacketWriter* writer, 45 EpollServer* epoll_server, 46 const QuicVersionVector& supported_versions); 47 virtual ~QuicTimeWaitListManager(); 48 49 // Adds the given guid to time wait state for kTimeWaitPeriod. Henceforth, 50 // any packet bearing this guid should not be processed while the guid remains 51 // in this list. If a non-NULL |close_packet| is provided, it is sent again 52 // when packets are received for added guids. If NULL, a public reset packet 53 // is sent with the specified |version|. DCHECKs that guid is not already on 54 // the list. 55 void AddGuidToTimeWait(QuicGuid guid, 56 QuicVersion version, 57 QuicEncryptedPacket* close_packet); // Owned. 58 59 // Returns true if the guid is in time wait state, false otherwise. Packets 60 // received for this guid should not lead to creation of new QuicSessions. 61 bool IsGuidInTimeWait(QuicGuid guid) const; 62 63 // Called when a packet is received for a guid that is in time wait state. 64 // Sends a public reset packet to the client which sent this guid. Sending 65 // of the public reset packet is throttled by using exponential back off. 66 // DCHECKs for the guid to be in time wait state. 67 // virtual to override in tests. 68 virtual void ProcessPacket(const IPEndPoint& server_address, 69 const IPEndPoint& client_address, 70 QuicGuid guid, 71 const QuicEncryptedPacket& packet); 72 73 // Called by the dispatcher when the underlying socket becomes writable again, 74 // since we might need to send pending public reset packets which we didn't 75 // send because the underlying socket was write blocked. 76 virtual bool OnCanWrite() OVERRIDE; 77 78 // Used to delete guid entries that have outlived their time wait period. 79 void CleanUpOldGuids(); 80 81 // QuicFramerVisitorInterface 82 virtual void OnError(QuicFramer* framer) OVERRIDE; 83 virtual bool OnProtocolVersionMismatch(QuicVersion received_version) OVERRIDE; 84 virtual bool OnUnauthenticatedHeader(const QuicPacketHeader& header) OVERRIDE; OnPacket()85 virtual void OnPacket() OVERRIDE {} OnPublicResetPacket(const QuicPublicResetPacket &)86 virtual void OnPublicResetPacket( 87 const QuicPublicResetPacket& /*packet*/) OVERRIDE {} OnVersionNegotiationPacket(const QuicVersionNegotiationPacket &)88 virtual void OnVersionNegotiationPacket( 89 const QuicVersionNegotiationPacket& /*packet*/) OVERRIDE {} 90 OnPacketComplete()91 virtual void OnPacketComplete() OVERRIDE {} 92 // The following methods should never get called because we always return 93 // false from OnUnauthenticatedHeader(). We never process the encrypted bytes. 94 virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE; 95 virtual void OnRevivedPacket() OVERRIDE; 96 virtual void OnFecProtectedPayload(base::StringPiece /*payload*/) OVERRIDE; 97 virtual bool OnStreamFrame(const QuicStreamFrame& /*frame*/) OVERRIDE; 98 virtual bool OnAckFrame(const QuicAckFrame& /*frame*/) OVERRIDE; 99 virtual bool OnCongestionFeedbackFrame( 100 const QuicCongestionFeedbackFrame& /*frame*/) OVERRIDE; 101 virtual bool OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) OVERRIDE; 102 virtual bool OnConnectionCloseFrame( 103 const QuicConnectionCloseFrame & /*frame*/) OVERRIDE; 104 virtual bool OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) OVERRIDE; 105 virtual void OnFecData(const QuicFecData& /*fec*/) OVERRIDE; 106 107 private: 108 friend class test::QuicTimeWaitListManagerPeer; 109 110 // Stores the guid and the time it was added to time wait state. 111 struct GuidAddTime; 112 // Internal structure to store pending public reset packets. 113 class QueuedPacket; 114 115 // Decides if a packet should be sent for this guid based on the number of 116 // received packets. 117 bool ShouldSendResponse(int received_packet_count); 118 119 // Given a GUID that exists in the time wait list, returns the QuicVersion 120 // associated with it. Used internally to set the framer version before 121 // writing the public reset packet. 122 QuicVersion GetQuicVersionFromGuid(QuicGuid guid); 123 124 // Creates a public reset packet and sends it or queues it to be sent later. 125 void SendPublicReset(const IPEndPoint& server_address, 126 const IPEndPoint& client_address, 127 QuicGuid guid, 128 QuicPacketSequenceNumber rejected_sequence_number); 129 130 // Either sends the packet and deletes it or makes pending_packets_queue_ the 131 // owner of the packet. 132 void SendOrQueuePacket(QueuedPacket* packet); 133 134 // Should only be called when write_blocked_ == false. We only care if the 135 // writing was unsuccessful because the socket got blocked, which can be 136 // tested using write_blocked_ == true. In case of all other errors we drop 137 // the packet. Hence, we return void. 138 void WriteToWire(QueuedPacket* packet); 139 140 // Register the alarm with the epoll server to wake up at appropriate time. 141 void SetGuidCleanUpAlarm(); 142 143 // A map from a recently closed guid to the number of packets received after 144 // the termination of the connection bound to the guid. 145 struct GuidData { GuidDataGuidData146 GuidData(int num_packets_, 147 QuicVersion version_, 148 QuicEncryptedPacket* close_packet) 149 : num_packets(num_packets_), 150 version(version_), 151 close_packet(close_packet) {} 152 int num_packets; 153 QuicVersion version; 154 QuicEncryptedPacket* close_packet; 155 }; 156 base::hash_map<QuicGuid, GuidData> guid_map_; 157 typedef base::hash_map<QuicGuid, GuidData>::iterator GuidMapIterator; 158 159 // Maintains a list of GuidAddTime elements which it owns, in the 160 // order they should be deleted. 161 std::deque<GuidAddTime*> time_ordered_guid_list_; 162 163 // Pending public reset packets that need to be sent out to the client 164 // when we are given a chance to write by the dispatcher. 165 std::deque<QueuedPacket*> pending_packets_queue_; 166 167 // Used to parse incoming packets. 168 QuicFramer framer_; 169 170 // Server and client address of the last packet processed. 171 IPEndPoint server_address_; 172 IPEndPoint client_address_; 173 174 // Used to schedule alarms to delete old guids which have been in the list for 175 // too long. Owned by the dispatcher. 176 EpollServer* epoll_server_; 177 178 // Time period for which guids should remain in time wait state. 179 const QuicTime::Delta kTimeWaitPeriod_; 180 181 // Alarm registered with the epoll server to clean up guids that have out 182 // lived their duration in time wait state. 183 scoped_ptr<GuidCleanUpAlarm> guid_clean_up_alarm_; 184 185 // Clock to efficiently measure approximate time from the epoll server. 186 QuicEpollClock clock_; 187 188 // Interface that writes given buffer to the socket. Owned by the dispatcher. 189 QuicPacketWriter* writer_; 190 191 // True if the underlying udp socket is write blocked, i.e will return EAGAIN 192 // on sendmsg. 193 bool is_write_blocked_; 194 195 DISALLOW_COPY_AND_ASSIGN(QuicTimeWaitListManager); 196 }; 197 198 } // namespace tools 199 } // namespace net 200 201 #endif // NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_ 202