Home | History | Annotate | Download | only in quic
      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