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#ifndef NET_QUIC_QUIC_UNACKED_PACKET_MAP_H_
6#define NET_QUIC_QUIC_UNACKED_PACKET_MAP_H_
7
8#include "net/base/linked_hash_map.h"
9#include "net/quic/quic_protocol.h"
10
11namespace net {
12
13// Class which tracks unacked packets for three purposes:
14// 1) Track retransmittable data, including multiple transmissions of frames.
15// 2) Track packets and bytes in flight for congestion control.
16// 3) Track sent time of packets to provide RTT measurements from acks.
17class NET_EXPORT_PRIVATE QuicUnackedPacketMap {
18 public:
19  QuicUnackedPacketMap();
20  ~QuicUnackedPacketMap();
21
22  // Adds |serialized_packet| to the map.  Does not mark it in flight.
23  void AddPacket(const SerializedPacket& serialized_packet);
24
25  // Called when a packet is retransmitted with a new sequence number.
26  // |old_sequence_number| will remain unacked, but will have no
27  // retransmittable data associated with it. |new_sequence_number| will
28  // be both unacked and associated with retransmittable data.
29  void OnRetransmittedPacket(QuicPacketSequenceNumber old_sequence_number,
30                             QuicPacketSequenceNumber new_sequence_number,
31                             TransmissionType transmission_type);
32
33  // Returns true if the packet |sequence_number| is unacked.
34  bool IsUnacked(QuicPacketSequenceNumber sequence_number) const;
35
36  // Sets the nack count to the max of the current nack count and |min_nacks|.
37  void NackPacket(QuicPacketSequenceNumber sequence_number,
38                  size_t min_nacks);
39
40  // Marks |sequence_number| as no longer in flight.
41  void RemoveFromInFlight(QuicPacketSequenceNumber sequence_number);
42
43  // Returns true if the unacked packet |sequence_number| has retransmittable
44  // frames.  This will return false if the packet has been acked, if a
45  // previous transmission of this packet was ACK'd, or if this packet has been
46  // retransmitted as with different sequence number, or if the packet never
47  // had any retransmittable packets in the first place.
48  bool HasRetransmittableFrames(QuicPacketSequenceNumber sequence_number) const;
49
50  // Returns true if there are any unacked packets.
51  bool HasUnackedPackets() const;
52
53  // Returns true if there are any unacked packets which have retransmittable
54  // frames.
55  bool HasUnackedRetransmittableFrames() const;
56
57  // Returns the largest sequence number that has been sent.
58  QuicPacketSequenceNumber largest_sent_packet() const {
59    return largest_sent_packet_;
60  }
61
62  // Returns the sum of bytes from all packets in flight.
63  QuicByteCount bytes_in_flight() const {
64    return bytes_in_flight_;
65  }
66
67  // Returns the smallest sequence number of a serialized packet which has not
68  // been acked by the peer.  If there are no unacked packets, returns 0.
69  QuicPacketSequenceNumber GetLeastUnackedSentPacket() const;
70
71  // Sets a packet as sent with the sent time |sent_time|.  Marks the packet
72  // as in flight if |set_in_flight| is true.
73  // Packets marked as in flight are expected to be marked as missing when they
74  // don't arrive, indicating the need for retransmission.
75  void SetSent(QuicPacketSequenceNumber sequence_number,
76               QuicTime sent_time,
77               QuicByteCount bytes_sent,
78               bool set_in_flight);
79
80  // Clears up to |num_to_clear| previous transmissions in order to make room
81  // in the ack frame for new acks.
82  void ClearPreviousRetransmissions(size_t num_to_clear);
83
84  typedef linked_hash_map<QuicPacketSequenceNumber,
85                          TransmissionInfo> UnackedPacketMap;
86
87  typedef UnackedPacketMap::const_iterator const_iterator;
88
89  const_iterator begin() const { return unacked_packets_.begin(); }
90  const_iterator end() const { return unacked_packets_.end(); }
91
92  // Returns true if there are unacked packets that are in flight.
93  bool HasInFlightPackets() const;
94
95  // Returns the TransmissionInfo associated with |sequence_number|, which
96  // must be unacked.
97  const TransmissionInfo& GetTransmissionInfo(
98      QuicPacketSequenceNumber sequence_number) const;
99
100  // Returns the time that the last unacked packet was sent.
101  QuicTime GetLastPacketSentTime() const;
102
103  // Returns the time that the first in flight packet was sent.
104  QuicTime GetFirstInFlightPacketSentTime() const;
105
106  // Returns the number of unacked packets.
107  size_t GetNumUnackedPackets() const;
108
109  // Returns true if there are multiple packets in flight.
110  bool HasMultipleInFlightPackets() const;
111
112  // Returns true if there are any pending crypto packets.
113  bool HasPendingCryptoPackets() const;
114
115  // Removes any retransmittable frames from this transmission or an associated
116  // transmission.  It removes now useless transmissions, and disconnects any
117  // other packets from other transmissions.
118  void RemoveRetransmittability(QuicPacketSequenceNumber sequence_number);
119
120  // Increases the largest observed.  Any packets less or equal to
121  // |largest_acked_packet| are discarded if they are only for the RTT purposes.
122  void IncreaseLargestObserved(QuicPacketSequenceNumber largest_observed);
123
124 private:
125  void MaybeRemoveRetransmittableFrames(TransmissionInfo* transmission_info);
126
127  // Returns true if the packet no longer has a purpose in the map.
128  bool IsPacketUseless(UnackedPacketMap::const_iterator it) const;
129
130  QuicPacketSequenceNumber largest_sent_packet_;
131  QuicPacketSequenceNumber largest_observed_;
132
133  // Newly serialized retransmittable and fec packets are added to this map,
134  // which contains owning pointers to any contained frames.  If a packet is
135  // retransmitted, this map will contain entries for both the old and the new
136  // packet. The old packet's retransmittable frames entry will be NULL, while
137  // the new packet's entry will contain the frames to retransmit.
138  // If the old packet is acked before the new packet, then the old entry will
139  // be removed from the map and the new entry's retransmittable frames will be
140  // set to NULL.
141  UnackedPacketMap unacked_packets_;
142
143  size_t bytes_in_flight_;
144  // Number of retransmittable crypto handshake packets.
145  size_t pending_crypto_packet_count_;
146
147  DISALLOW_COPY_AND_ASSIGN(QuicUnackedPacketMap);
148};
149
150}  // namespace net
151
152#endif  // NET_QUIC_QUIC_UNACKED_PACKET_MAP_H_
153