// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Handles packets for guids in time wait state by discarding the packet and
// sending the clients a public reset packet with exponential backoff.

#ifndef NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_
#define NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_

#include <deque>

#include "base/containers/hash_tables.h"
#include "base/strings/string_piece.h"
#include "net/quic/quic_blocked_writer_interface.h"
#include "net/quic/quic_framer.h"
#include "net/quic/quic_protocol.h"
#include "net/tools/flip_server/epoll_server.h"
#include "net/tools/quic/quic_epoll_clock.h"
#include "net/tools/quic/quic_packet_writer.h"

namespace net {
namespace tools {

class GuidCleanUpAlarm;

// Maintains a list of all guids that have been recently closed. A guid lives in
// this state for kTimeWaitPeriod. All packets received for guids in this state
// are handed over to the QuicTimeWaitListManager by the QuicDispatcher. It also
// decides whether we should send a public reset packet to the client which sent
// a packet with the guid in time wait state and sends it when appropriate.
// After the guid expires its time wait period, a new connection/session will be
// created if a packet is received for this guid.
class QuicTimeWaitListManager : public QuicBlockedWriterInterface,
                                public QuicFramerVisitorInterface {
 public:
  // writer - the entity that writes to the socket. (Owned by the dispatcher)
  // epoll_server - used to run clean up alarms. (Owned by the dispatcher)
  QuicTimeWaitListManager(QuicPacketWriter* writer,
                          EpollServer* epoll_server);
  virtual ~QuicTimeWaitListManager();

  // Adds the given guid to time wait state for kTimeWaitPeriod. Henceforth,
  // any packet bearing this guid should not be processed while the guid remains
  // in this list. Public reset packets are sent to the clients by the time wait
  // list manager that send packets to guids in this state. DCHECKs that guid is
  // not already on the list.
  void AddGuidToTimeWait(QuicGuid guid);

  // Returns true if the guid is in time wait state, false otherwise. Packets
  // received for this guid should not lead to creation of new QuicSessions.
  bool IsGuidInTimeWait(QuicGuid guid) const;

  // Called when a packet is received for a guid that is in time wait state.
  // Sends a public reset packet to the client which sent this guid. Sending
  // of the public reset packet is throttled by using exponential back off.
  // DCHECKs for the guid to be in time wait state.
  // virtual to override in tests.
  virtual void ProcessPacket(const IPEndPoint& server_address,
                             const IPEndPoint& client_address,
                             QuicGuid guid,
                             const QuicEncryptedPacket& packet);

  // Called by the dispatcher when the underlying socket becomes writable again,
  // since we might need to send pending public reset packets which we didn't
  // send because the underlying socket was write blocked.
  virtual bool OnCanWrite() OVERRIDE;

  // Used to delete guid entries that have outlived their time wait period.
  void CleanUpOldGuids();

  // FramerVisitorInterface
  virtual void OnError(QuicFramer* framer) OVERRIDE;
  virtual bool OnProtocolVersionMismatch(QuicTag received_version) OVERRIDE;
  virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE;
  virtual void OnPacket() OVERRIDE {}
  virtual void OnPublicResetPacket(
      const QuicPublicResetPacket& packet) OVERRIDE {}
  virtual void OnVersionNegotiationPacket(
      const QuicVersionNegotiationPacket& /*packet*/) OVERRIDE {}

  virtual void OnPacketComplete() OVERRIDE {}
  // The following methods should never get called because we always return
  // false from OnPacketHeader(). We never need to process body of a packet.
  virtual void OnRevivedPacket() OVERRIDE {}
  virtual void OnFecProtectedPayload(base::StringPiece payload) OVERRIDE {}
  virtual bool OnStreamFrame(const QuicStreamFrame& frame) OVERRIDE;
  virtual bool OnAckFrame(const QuicAckFrame& frame) OVERRIDE;
  virtual bool OnCongestionFeedbackFrame(
      const QuicCongestionFeedbackFrame& frame) OVERRIDE;
  virtual bool OnRstStreamFrame(const QuicRstStreamFrame& frame) OVERRIDE;
  virtual bool OnConnectionCloseFrame(
      const QuicConnectionCloseFrame & frame) OVERRIDE;
  virtual bool OnGoAwayFrame(const QuicGoAwayFrame& frame) OVERRIDE;
  virtual void OnFecData(const QuicFecData& fec) OVERRIDE {}

 protected:
  // Exposed for tests.
  bool is_write_blocked() const { return is_write_blocked_; }

  // Decides if public reset packet should be sent for this guid based on the
  // number of received pacekts.
  bool ShouldSendPublicReset(int received_packet_count);

  // Exposed for tests.
  const QuicTime::Delta time_wait_period() const { return kTimeWaitPeriod_; }

 private:
  // Stores the guid and the time it was added to time wait state.
  struct GuidAddTime;
  // Internal structure to store pending public reset packets.
  class QueuedPacket;

  // Creates a public reset packet and sends it or queues it to be sent later.
  void SendPublicReset(const IPEndPoint& server_address,
                       const IPEndPoint& client_address,
                       QuicGuid guid,
                       QuicPacketSequenceNumber rejected_sequence_number);

  // Either sends the packet and deletes it or makes pending_packets_queue_ the
  // owner of the packet.
  void SendOrQueuePacket(QueuedPacket* packet);

  // Should only be called when write_blocked_ == false. We only care if the
  // writing was unsuccessful because the socket got blocked, which can be
  // tested using write_blocked_ == true. In case of all other errors we drop
  // the packet. Hence, we return void.
  void WriteToWire(QueuedPacket* packet);

  // Register the alarm with the epoll server to wake up at appropriate time.
  void SetGuidCleanUpAlarm();

  // A map from a recently closed guid to the number of packets received after
  // the termination of the connection bound to the guid.
  base::hash_map<QuicGuid, int> guid_map_;
  typedef base::hash_map<QuicGuid, int>::iterator GuidMapIterator;

  // Maintains a list of GuidAddTime elements which it owns, in the
  // order they should be deleted.
  std::deque<GuidAddTime*> time_ordered_guid_list_;

  // Pending public reset packets that need to be sent out to the client
  // when we are given a chance to write by the dispatcher.
  std::deque<QueuedPacket*> pending_packets_queue_;

  // Used to parse incoming packets.
  QuicFramer framer_;

  // Server and client address of the last packet processed.
  IPEndPoint server_address_;
  IPEndPoint client_address_;

  // Used to schedule alarms to delete old guids which have been in the list for
  // too long. Owned by the dispatcher.
  EpollServer* epoll_server_;

  // Time period for which guids should remain in time wait state.
  const QuicTime::Delta kTimeWaitPeriod_;

  // Alarm registered with the epoll server to clean up guids that have out
  // lived their duration in time wait state.
  scoped_ptr<GuidCleanUpAlarm> guid_clean_up_alarm_;

  // Clock to efficiently measure approximate time from the epoll server.
  QuicEpollClock clock_;

  // Interface that writes given buffer to the socket. Owned by the dispatcher.
  QuicPacketWriter* writer_;

  // True if the underlying udp socket is write blocked, i.e will return EAGAIN
  // on sendmsg.
  bool is_write_blocked_;

  DISALLOW_COPY_AND_ASSIGN(QuicTimeWaitListManager);
};

}  // namespace tools
}  // namespace net

#endif  // NET_TOOLS_QUIC_QUIC_TIME_WAIT_LIST_MANAGER_H_
