Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / quic / quic_sent_packet_manager.h
index 206a0da..f82e34b 100644 (file)
@@ -5,10 +5,7 @@
 #ifndef NET_QUIC_QUIC_SENT_PACKET_MANAGER_H_
 #define NET_QUIC_QUIC_SENT_PACKET_MANAGER_H_
 
-#include <deque>
-#include <list>
 #include <map>
-#include <queue>
 #include <set>
 #include <utility>
 #include <vector>
 #include "base/containers/hash_tables.h"
 #include "base/memory/scoped_ptr.h"
 #include "net/base/linked_hash_map.h"
+#include "net/quic/congestion_control/loss_detection_interface.h"
+#include "net/quic/congestion_control/rtt_stats.h"
 #include "net/quic/congestion_control/send_algorithm_interface.h"
 #include "net/quic/quic_ack_notifier_manager.h"
 #include "net/quic/quic_protocol.h"
-
-NET_EXPORT_PRIVATE extern bool FLAGS_track_retransmission_history;
-NET_EXPORT_PRIVATE extern bool FLAGS_enable_quic_pacing;
+#include "net/quic/quic_sustained_bandwidth_recorder.h"
+#include "net/quic/quic_unacked_packet_map.h"
 
 namespace net {
 
@@ -41,6 +39,38 @@ struct QuicConnectionStats;
 // previous transmission is acked, the data will not be retransmitted.
 class NET_EXPORT_PRIVATE QuicSentPacketManager {
  public:
+  // Interface which gets callbacks from the QuicSentPacketManager at
+  // interesting points.  Implementations must not mutate the state of
+  // the packet manager or connection as a result of these callbacks.
+  class NET_EXPORT_PRIVATE DebugDelegate {
+   public:
+    virtual ~DebugDelegate() {}
+
+    // Called when a spurious retransmission is detected.
+    virtual void OnSpuriousPacketRetransmition(
+        TransmissionType transmission_type,
+        QuicByteCount byte_size) {}
+
+    virtual void OnIncomingAck(
+        const QuicAckFrame& ack_frame,
+        QuicTime ack_receive_time,
+        QuicPacketSequenceNumber largest_observed,
+        bool largest_observed_acked,
+        QuicPacketSequenceNumber least_unacked_sent_packet) {}
+  };
+
+  // Interface which gets callbacks from the QuicSentPacketManager when
+  // network-related state changes. Implementations must not mutate the
+  // state of the packet manager as a result of these callbacks.
+  class NET_EXPORT_PRIVATE NetworkChangeVisitor {
+   public:
+    virtual ~NetworkChangeVisitor() {}
+
+    // Called when congestion window may have changed.
+    virtual void OnCongestionWindowChange() = 0;
+    // TODO(jri): Add OnRttStatsChange() to this class as well.
+  };
+
   // Struct to store the pending retransmission information.
   struct PendingRetransmission {
     PendingRetransmission(QuicPacketSequenceNumber sequence_number,
@@ -62,39 +92,33 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
   QuicSentPacketManager(bool is_server,
                         const QuicClock* clock,
                         QuicConnectionStats* stats,
-                        CongestionFeedbackType congestion_type);
+                        CongestionControlType congestion_control_type,
+                        LossDetectionType loss_type);
   virtual ~QuicSentPacketManager();
 
   virtual void SetFromConfig(const QuicConfig& config);
 
-  virtual void SetMaxPacketSize(QuicByteCount max_packet_size);
+  void SetNumOpenStreams(size_t num_streams);
 
-  // Called when a new packet is serialized.  If the packet contains
-  // retransmittable data, it will be added to the unacked packet map.
-  void OnSerializedPacket(const SerializedPacket& serialized_packet);
-
-  // Called when a packet is retransmitted with a new sequence number.
-  // Replaces the old entry in the unacked packet map with the new
-  // sequence number.
-  void OnRetransmittedPacket(QuicPacketSequenceNumber old_sequence_number,
-                             QuicPacketSequenceNumber new_sequence_number);
+  void SetHandshakeConfirmed() { handshake_confirmed_ = true; }
 
-  // Processes the incoming ack and returns true if the retransmission or ack
-  // alarm should be reset.
-  bool OnIncomingAck(const ReceivedPacketInfo& received_info,
+  // Processes the incoming ack.
+  void OnIncomingAck(const QuicAckFrame& ack_frame,
                      QuicTime ack_receive_time);
 
-  // Discards any information for the packet corresponding to |sequence_number|.
-  // If this packet has been retransmitted, information on those packets
-  // will be discarded as well.  Also discards it from the congestion window if
-  // it is present.
-  void DiscardUnackedPacket(QuicPacketSequenceNumber sequence_number);
-
   // Returns true if the non-FEC packet |sequence_number| is unacked.
   bool IsUnacked(QuicPacketSequenceNumber sequence_number) const;
 
   // Requests retransmission of all unacked packets of |retransmission_type|.
-  void RetransmitUnackedPackets(RetransmissionType retransmission_type);
+  void RetransmitUnackedPackets(TransmissionType retransmission_type);
+
+  // Retransmits the oldest pending packet there is still a tail loss probe
+  // pending.  Invoked after OnRetransmissionTimeout.
+  bool MaybeRetransmitTailLossProbe();
+
+  // Removes the retransmittable frames from all unencrypted packets to ensure
+  // they don't get retransmitted.
+  void NeuterUnencryptedPackets();
 
   // Returns true if the unacked packet |sequence_number| has retransmittable
   // frames.  This will only return false if the packet has been acked, if a
@@ -110,16 +134,9 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
 
   bool HasUnackedPackets() const;
 
-  // Returns the number of unacked packets which have retransmittable frames.
-  size_t GetNumRetransmittablePackets() const;
-
   // Returns the smallest sequence number of a serialized packet which has not
-  // been acked by the peer.  If there are no unacked packets, returns 0.
-  QuicPacketSequenceNumber GetLeastUnackedSentPacket() const;
-
-  // Returns the set of sequence numbers of all unacked packets.
-  // Test only.
-  SequenceNumberSet GetUnackedPackets() const;
+  // been acked by the peer.
+  QuicPacketSequenceNumber GetLeastUnacked() const;
 
   // Called when a congestion feedback frame is received from peer.
   virtual void OnIncomingQuicCongestionFeedbackFrame(
@@ -129,7 +146,8 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
   // Called when we have sent bytes to the peer.  This informs the manager both
   // the number of bytes sent and if they were retransmitted.  Returns true if
   // the sender should reset the retransmission timer.
-  virtual bool OnPacketSent(QuicPacketSequenceNumber sequence_number,
+  virtual bool OnPacketSent(SerializedPacket* serialized_packet,
+                            QuicPacketSequenceNumber original_sequence_number,
                             QuicTime sent_time,
                             QuicByteCount bytes,
                             TransmissionType transmission_type,
@@ -144,9 +162,7 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
   // Note 2: Send algorithms may or may not use |retransmit| in their
   // calculations.
   virtual QuicTime::Delta TimeUntilSend(QuicTime now,
-                                        TransmissionType transmission_type,
-                                        HasRetransmittableData retransmittable,
-                                        IsHandshake handshake);
+                                        HasRetransmittableData retransmittable);
 
   // Returns amount of time for delayed ack timer.
   const QuicTime::Delta DelayedAckTime() const;
@@ -156,82 +172,96 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
   // there are no retransmittable packets.
   const QuicTime GetRetransmissionTime() const;
 
-  // Returns the estimated smoothed RTT calculated by the congestion algorithm.
-  const QuicTime::Delta SmoothedRtt() const;
+  const RttStats* GetRttStats() const;
 
   // Returns the estimated bandwidth calculated by the congestion algorithm.
   QuicBandwidth BandwidthEstimate() const;
 
-  // Returns the size of the current congestion window in bytes.  Note, this is
-  // not the *available* window.  Some send algorithms may not use a congestion
-  // window and will return 0.
-  QuicByteCount GetCongestionWindow() const;
+  // Returns true if the current instantaneous bandwidth estimate is reliable.
+  bool HasReliableBandwidthEstimate() const;
+
+  const QuicSustainedBandwidthRecorder& SustainedBandwidthRecorder() const;
 
-  // Enables pacing if it has not already been enabled, and if
-  // FLAGS_enable_quic_pacing is set.
-  void MaybeEnablePacing();
+  // Returns the size of the current congestion window in number of
+  // kDefaultTCPMSS-sized segments. Note, this is not the *available* window.
+  // Some send algorithms may not use a congestion window and will return 0.
+  QuicPacketCount GetCongestionWindowInTcpMss() const;
+
+  // Returns the number of packets of length |max_packet_length| which fit in
+  // the current congestion window. More packets may end up in flight if the
+  // congestion window has been recently reduced, of if non-full packets are
+  // sent.
+  QuicPacketCount EstimateMaxPacketsInFlight(
+      QuicByteCount max_packet_length) const;
+
+  // Returns the size of the slow start congestion window in nume of 1460 byte
+  // TCP segments, aka ssthresh.  Some send algorithms do not define a slow
+  // start threshold and will return 0.
+  QuicPacketCount GetSlowStartThresholdInTcpMss() const;
+
+  // Enables pacing if it has not already been enabled.
+  void EnablePacing();
 
   bool using_pacing() const { return using_pacing_; }
 
+  void set_debug_delegate(DebugDelegate* debug_delegate) {
+    debug_delegate_ = debug_delegate;
+  }
+
+  QuicPacketSequenceNumber largest_observed() const {
+    return unacked_packets_.largest_observed();
+  }
+
+  QuicPacketSequenceNumber least_packet_awaited_by_peer() {
+    return least_packet_awaited_by_peer_;
+  }
+
+  void set_network_change_visitor(NetworkChangeVisitor* visitor) {
+    DCHECK(!network_change_visitor_);
+    DCHECK(visitor);
+    network_change_visitor_ = visitor;
+  }
+
+  size_t consecutive_rto_count() const {
+    return consecutive_rto_count_;
+  }
+
+  size_t consecutive_tlp_count() const {
+    return consecutive_tlp_count_;
+  }
 
  private:
   friend class test::QuicConnectionPeer;
   friend class test::QuicSentPacketManagerPeer;
 
-  enum ReceivedByPeer {
-    RECEIVED_BY_PEER,
-    NOT_RECEIVED_BY_PEER,
-  };
-
+  // The retransmission timer is a single timer which switches modes depending
+  // upon connection state.
   enum RetransmissionTimeoutMode {
+    // A conventional TCP style RTO.
     RTO_MODE,
+    // A tail loss probe.  By default, QUIC sends up to two before RTOing.
     TLP_MODE,
+    // Retransmission of handshake packets prior to handshake completion.
     HANDSHAKE_MODE,
+    // Re-invoke the loss detection when a packet is not acked before the
+    // loss detection algorithm expects.
+    LOSS_MODE,
   };
 
-  struct NET_EXPORT_PRIVATE TransmissionInfo {
-    TransmissionInfo();
-
-    // Constructs a Transmission with a new all_tranmissions set
-    // containing |sequence_number|.
-    TransmissionInfo(RetransmittableFrames* retransmittable_frames,
-                     QuicPacketSequenceNumber sequence_number,
-                     QuicSequenceNumberLength sequence_number_length);
-
-    // Constructs a Transmission with the specified |all_tranmissions| set
-    // and inserts |sequence_number| into it.
-    TransmissionInfo(RetransmittableFrames* retransmittable_frames,
-                     QuicPacketSequenceNumber sequence_number,
-                     QuicSequenceNumberLength sequence_number_length,
-                     SequenceNumberSet* all_transmissions);
-
-    RetransmittableFrames* retransmittable_frames;
-    QuicSequenceNumberLength sequence_number_length;
-    // Zero when the packet is serialized, non-zero once it's sent.
-    QuicTime sent_time;
-    // Stores the sequence numbers of all transmissions of this packet.
-    // Can never be null.
-    SequenceNumberSet* all_transmissions;
-    // Pending packets have not been abandoned or lost.
-    bool pending;
-  };
-
-  typedef linked_hash_map<QuicPacketSequenceNumber,
-                          TransmissionInfo> UnackedPacketMap;
   typedef linked_hash_map<QuicPacketSequenceNumber,
                           TransmissionType> PendingRetransmissionMap;
 
-  static bool HasCryptoHandshake(const TransmissionInfo& transmission_info);
+  // Called when a packet is retransmitted with a new sequence number.
+  // Replaces the old entry in the unacked packet map with the new
+  // sequence number.
+  void OnRetransmittedPacket(QuicPacketSequenceNumber old_sequence_number,
+                             QuicPacketSequenceNumber new_sequence_number);
 
-  // Returns true if there are unacked packets that are pending.
-  bool HasPendingPackets() const;
+  // Updates the least_packet_awaited_by_peer.
+  void UpdatePacketInformationReceivedByPeer(const QuicAckFrame& ack_frame);
 
   // Process the incoming ack looking for newly ack'd data packets.
-  void HandleAckForSentPackets(const ReceivedPacketInfo& received_info);
-
-  // Called when a packet is timed out, such as an RTO.  Removes the bytes from
-  // the congestion manager, but does not change the congestion window size.
-  virtual void OnPacketAbandoned(UnackedPacketMap::iterator it);
+  void HandleAckForSentPackets(const QuicAckFrame& ack_frame);
 
   // Returns the current retransmission mode.
   RetransmissionTimeoutMode GetRetransmissionMode() const;
@@ -239,9 +269,6 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
   // Retransmits all crypto stream packets.
   void RetransmitCryptoPackets();
 
-  // Retransmits the oldest pending packet.
-  void RetransmitOldestPacket();
-
   // Retransmits all the packets and abandons by invoking a full RTO.
   void RetransmitAllPackets();
 
@@ -255,23 +282,33 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
   const QuicTime::Delta GetRetransmissionDelay() const;
 
   // Update the RTT if the ack is for the largest acked sequence number.
-  void MaybeUpdateRTT(const ReceivedPacketInfo& received_info,
+  // Returns true if the rtt was updated.
+  bool MaybeUpdateRTT(const QuicAckFrame& ack_frame,
                       const QuicTime& ack_receive_time);
 
-  // Chooses whether to nack retransmit any packets based on the receipt info.
-  // All acks have been handled before this method is invoked.
-  void MaybeRetransmitOnAckFrame(const ReceivedPacketInfo& received_info,
-                                 const QuicTime& ack_receive_time);
-
-  // Marks |sequence_number| as being fully handled, either due to receipt
-  // by the peer, or having been discarded as indecipherable.  Returns an
-  // iterator to the next remaining unacked packet.
-  UnackedPacketMap::iterator MarkPacketHandled(
-      QuicPacketSequenceNumber sequence_number,
-      ReceivedByPeer received_by_peer);
-
-  // Removes entries from the unacked packet map.
-  void RemovePacket(QuicPacketSequenceNumber sequence_number);
+  // Invokes the loss detection algorithm and loses and retransmits packets if
+  // necessary.
+  void InvokeLossDetection(QuicTime time);
+
+  // Invokes OnCongestionEvent if |rtt_updated| is true, there are pending acks,
+  // or pending losses.  Clears pending acks and pending losses afterwards.
+  // |bytes_in_flight| is the number of bytes in flight before the losses or
+  // acks.
+  void MaybeInvokeCongestionEvent(bool rtt_updated,
+                                  QuicByteCount bytes_in_flight);
+
+  // Marks |sequence_number| as having been revived by the peer, but not
+  // received, so the packet remains pending if it is and the congestion control
+  // does not consider the packet acked.
+  void MarkPacketRevived(QuicPacketSequenceNumber sequence_number,
+                         QuicTime::Delta delta_largest_observed);
+
+  // Removes the retransmittability and pending properties from the packet at
+  // |it| due to receipt by the peer.  Returns an iterator to the next remaining
+  // unacked packet.
+  void MarkPacketHandled(QuicPacketSequenceNumber sequence_number,
+                         const TransmissionInfo& info,
+                         QuicTime::Delta delta_largest_observed);
 
   // Request that |sequence_number| be retransmitted after the other pending
   // retransmissions.  Does not add it to the retransmissions if it's already
@@ -279,21 +316,25 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
   void MarkForRetransmission(QuicPacketSequenceNumber sequence_number,
                              TransmissionType transmission_type);
 
-  // Clears up to |num_to_clear| previous transmissions in order to make room
-  // in the ack frame for new acks.
-  void ClearPreviousRetransmissions(size_t num_to_clear);
+  // Notify observers about spurious retransmits.
+  void RecordSpuriousRetransmissions(
+      const SequenceNumberList& all_transmissions,
+      QuicPacketSequenceNumber acked_sequence_number);
 
-  void CleanupPacketHistory();
+  // Returns true if the client is sending or the server has received a
+  // connection option.
+  bool HasClientSentConnectionOption(const QuicConfig& config,
+                                     QuicTag tag) const;
 
   // Newly serialized retransmittable and fec packets are added to this map,
   // which contains owning pointers to any contained frames.  If a packet is
   // retransmitted, this map will contain entries for both the old and the new
-  // packet. The old packet's retransmittable frames entry will be NULL, while
-  // the new packet's entry will contain the frames to retransmit.
+  // packet. The old packet's retransmittable frames entry will be nullptr,
+  // while the new packet's entry will contain the frames to retransmit.
   // If the old packet is acked before the new packet, then the old entry will
   // be removed from the map and the new entry's retransmittable frames will be
-  // set to NULL.
-  UnackedPacketMap unacked_packets_;
+  // set to nullptr.
+  QuicUnackedPacketMap unacked_packets_;
 
   // Pending retransmissions which have not been packetized and sent yet.
   PendingRetransmissionMap pending_retransmissions_;
@@ -308,23 +349,48 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
 
   const QuicClock* clock_;
   QuicConnectionStats* stats_;
+  DebugDelegate* debug_delegate_;
+  NetworkChangeVisitor* network_change_visitor_;
+  RttStats rtt_stats_;
   scoped_ptr<SendAlgorithmInterface> send_algorithm_;
-  // Tracks the send time, size, and nack count of sent packets.  Packets are
-  // removed after 5 seconds and they've been removed from pending_packets_.
-  SendAlgorithmInterface::SentPacketsMap packet_history_map_;
-  QuicTime::Delta rtt_sample_;  // RTT estimate from the most recent ACK.
-  // Number of outstanding crypto handshake packets.
-  size_t pending_crypto_packet_count_;
+  scoped_ptr<LossDetectionInterface> loss_algorithm_;
+  bool n_connection_simulation_;
+
+  // Receiver side buffer in bytes.
+  QuicByteCount receive_buffer_bytes_;
+
+  // Least sequence number which the peer is still waiting for.
+  QuicPacketSequenceNumber least_packet_awaited_by_peer_;
+
+  // Tracks the first RTO packet.  If any packet before that packet gets acked,
+  // it indicates the RTO was spurious and should be reversed(F-RTO).
+  QuicPacketSequenceNumber first_rto_transmission_;
   // Number of times the RTO timer has fired in a row without receiving an ack.
   size_t consecutive_rto_count_;
   // Number of times the tail loss probe has been sent.
   size_t consecutive_tlp_count_;
   // Number of times the crypto handshake has been retransmitted.
   size_t consecutive_crypto_retransmission_count_;
+  // Number of pending transmissions of TLP or crypto packets.
+  size_t pending_timer_transmission_count_;
   // Maximum number of tail loss probes to send before firing an RTO.
   size_t max_tail_loss_probes_;
   bool using_pacing_;
 
+  // Vectors packets acked and lost as a result of the last congestion event.
+  SendAlgorithmInterface::CongestionVector packets_acked_;
+  SendAlgorithmInterface::CongestionVector packets_lost_;
+
+  // Set to true after the crypto handshake has successfully completed. After
+  // this is true we no longer use HANDSHAKE_MODE, and further frames sent on
+  // the crypto stream (i.e. SCUP messages) are treated like normal
+  // retransmittable frames.
+  bool handshake_confirmed_;
+
+  // Records bandwidth from server to client in normal operation, over periods
+  // of time with no loss events.
+  QuicSustainedBandwidthRecorder sustained_bandwidth_recorder_;
+
   DISALLOW_COPY_AND_ASSIGN(QuicSentPacketManager);
 };