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