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