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