summaryrefslogtreecommitdiffstats
path: root/net/quic/quic_unacked_packet_map.h
blob: a687bb64a4ff2ce0009b9f35a5bd32af5b78da7c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Copyright 2014 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.

#ifndef NET_QUIC_QUIC_UNACKED_PACKET_MAP_H_
#define NET_QUIC_QUIC_UNACKED_PACKET_MAP_H_

#include "net/base/linked_hash_map.h"
#include "net/quic/quic_protocol.h"

namespace net {

// Class which tracks unacked packets, including those packets which are
// currently pending, and the relationship between packets which
// contain the same data (via retransmissions)
class NET_EXPORT_PRIVATE QuicUnackedPacketMap {
 public:
  struct NET_EXPORT_PRIVATE TransmissionInfo {
    // Used by STL when assinging into a map.
    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;
    // Zero when the packet is serialized, non-zero once it's sent.
    QuicByteCount bytes_sent;
    size_t nack_count;
    // 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;
  };

  QuicUnackedPacketMap();
  ~QuicUnackedPacketMap();

  // Adds |serialized_packet| to the map.  Does not mark it pending.
  void AddPacket(const SerializedPacket& serialized_packet);

  // Called when a packet is retransmitted with a new sequence number.
  // |old_sequence_number| will remain unacked, but will have no
  // retransmittable data associated with it. |new_sequence_number| will
  // be both unacked and associated with retransmittable data.
  void OnRetransmittedPacket(QuicPacketSequenceNumber old_sequence_number,
                             QuicPacketSequenceNumber new_sequence_number);

  // Returns true if the packet |sequence_number| is unacked.
  bool IsUnacked(QuicPacketSequenceNumber sequence_number) const;

  // Returns true if the packet |sequence_number| is pending.
  bool IsPending(QuicPacketSequenceNumber sequence_number) const;

  // Sets the nack count to the max of the current nack count and |min_nacks|.
  void NackPacket(QuicPacketSequenceNumber sequence_number,
                  size_t min_nacks);

  // Marks |sequence_number| as no longer pending.
  void SetNotPending(QuicPacketSequenceNumber sequence_number);

  // Returns true if the unacked packet |sequence_number| has retransmittable
  // frames.  This will return false if the packet has been acked, if a
  // previous transmission of this packet was ACK'd, or if this packet has been
  // retransmitted as with different sequence number, or if the packet never
  // had any retransmittable packets in the first place.
  bool HasRetransmittableFrames(QuicPacketSequenceNumber sequence_number) const;

  // Returns true if there are any unacked packets.
  bool HasUnackedPackets() const;

  // Returns true if there are any unacked packets which have retransmittable
  // frames.
  bool HasUnackedRetransmittableFrames() const;

  // Returns the number of unacked packets which have retransmittable frames.
  size_t GetNumRetransmittablePackets() const;

  // Returns the largest sequence number that has been sent.
  QuicPacketSequenceNumber largest_sent_packet() const {
    return largest_sent_packet_;
  }

  // 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;

  // Sets a packet as sent with the sent time |sent_time|.  Marks the packet
  // as pending and tracks the |bytes_sent| if |set_pending| is true.
  // Packets marked as pending are expected to be marked as missing when they
  // don't arrive, indicating the need for retransmission.
  void SetSent(QuicPacketSequenceNumber sequence_number,
               QuicTime sent_time,
               QuicByteCount bytes_sent,
               bool set_pending);

  // 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);

  typedef linked_hash_map<QuicPacketSequenceNumber,
                          TransmissionInfo> UnackedPacketMap;

  typedef UnackedPacketMap::const_iterator const_iterator;

  const_iterator begin() const { return unacked_packets_.begin(); }
  const_iterator end() const { return unacked_packets_.end(); }

  // Returns true if there are unacked packets that are pending.
  bool HasPendingPackets() const;

  // Returns the TransmissionInfo associated with |sequence_number|, which
  // must be unacked.
  const TransmissionInfo& GetTransmissionInfo(
      QuicPacketSequenceNumber sequence_number) const;

  // Returns the time that the last unacked packet was sent.
  QuicTime GetLastPacketSentTime() const;

  // Returns the time that the first pending packet was sent.
  QuicTime GetFirstPendingPacketSentTime() const;

  // Returns the number of unacked packets.
  size_t GetNumUnackedPackets() const;

  // Returns true if there are multiple packet pending.
  bool HasMultiplePendingPackets() const;

  // Returns true if there are any pending crypto packets.
  bool HasPendingCryptoPackets() const;

  // Removes entries from the unacked packet map, and deletes
  // the retransmittable frames associated with the packet.
  // Does not remove any previous or subsequent transmissions of this packet.
  void RemovePacket(QuicPacketSequenceNumber sequence_number);

  // Neuters the specified packet.  Deletes any retransmittable
  // frames, and sets all_transmissions to only include itself.
  void NeuterPacket(QuicPacketSequenceNumber sequence_number);

  // Returns true if the packet has been marked as sent by SetSent.
  static bool IsSentAndNotPending(const TransmissionInfo& transmission_info);

 private:
  QuicPacketSequenceNumber largest_sent_packet_;

  // 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.
  // 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_;

  size_t bytes_in_flight_;
  // Number of outstanding crypto handshake packets.
  size_t pending_crypto_packet_count_;

  DISALLOW_COPY_AND_ASSIGN(QuicUnackedPacketMap);
};

}  // namespace net

#endif  // NET_QUIC_QUIC_UNACKED_PACKET_MAP_H_