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