blob: 64d1da83a7e6006f58582b74477be12dfe798a40 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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 QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_
6#define QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_
7
8#include <cstddef>
9#include <deque>
10
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include "net/third_party/quiche/src/quic/core/quic_packets.h"
12#include "net/third_party/quiche/src/quic/core/quic_transmission_info.h"
13#include "net/third_party/quiche/src/quic/core/session_notifier_interface.h"
14#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
15
16namespace quic {
17
18namespace test {
19class QuicUnackedPacketMapPeer;
20} // namespace test
21
22// Class which tracks unacked packets for three purposes:
23// 1) Track retransmittable data, including multiple transmissions of frames.
24// 2) Track packets and bytes in flight for congestion control.
25// 3) Track sent time of packets to provide RTT measurements from acks.
26class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap {
27 public:
28 QuicUnackedPacketMap(Perspective perspective);
29 QuicUnackedPacketMap(const QuicUnackedPacketMap&) = delete;
30 QuicUnackedPacketMap& operator=(const QuicUnackedPacketMap&) = delete;
31 ~QuicUnackedPacketMap();
32
33 // Adds |serialized_packet| to the map and marks it as sent at |sent_time|.
34 // Marks the packet as in flight if |set_in_flight| is true.
35 // Packets marked as in flight are expected to be marked as missing when they
36 // don't arrive, indicating the need for retransmission.
37 // |old_packet_number| is the packet number of the previous transmission,
38 // or 0 if there was none.
39 // Any AckNotifierWrappers in |serialized_packet| are swapped from the
40 // serialized packet into the QuicTransmissionInfo.
41 void AddSentPacket(SerializedPacket* serialized_packet,
42 QuicPacketNumber old_packet_number,
43 TransmissionType transmission_type,
44 QuicTime sent_time,
45 bool set_in_flight);
46
47 // Returns true if the packet |packet_number| is unacked.
48 bool IsUnacked(QuicPacketNumber packet_number) const;
49
50 // Notifies session_notifier that frames have been acked. Returns true if any
51 // new data gets acked, returns false otherwise.
52 bool NotifyFramesAcked(const QuicTransmissionInfo& info,
QUICHE team9467db02019-05-30 09:38:45 -070053 QuicTime::Delta ack_delay,
54 QuicTime receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -050055
56 // Notifies session_notifier that frames in |info| are considered as lost.
57 void NotifyFramesLost(const QuicTransmissionInfo& info,
58 TransmissionType type);
59
60 // Notifies session_notifier to retransmit frames in |info| with
61 // |transmission_type|.
62 void RetransmitFrames(const QuicTransmissionInfo& info,
63 TransmissionType type);
64
65 // Marks |info| as no longer in flight.
66 void RemoveFromInFlight(QuicTransmissionInfo* info);
67
68 // Marks |packet_number| as no longer in flight.
69 void RemoveFromInFlight(QuicPacketNumber packet_number);
70
71 // No longer retransmit data for |stream_id|.
72 void CancelRetransmissionsForStream(QuicStreamId stream_id);
73
74 // Returns true if |packet_number| has retransmittable frames. This will
75 // return false if all frames of this packet are either non-retransmittable or
76 // have been acked.
77 bool HasRetransmittableFrames(QuicPacketNumber packet_number) const;
78
79 // Returns true if |info| has retransmittable frames. This will return false
80 // if all frames of this packet are either non-retransmittable or have been
81 // acked.
82 bool HasRetransmittableFrames(const QuicTransmissionInfo& info) const;
83
84 // Returns true if there are any unacked packets which have retransmittable
85 // frames.
86 bool HasUnackedRetransmittableFrames() const;
87
88 // Returns true if there are no packets present in the unacked packet map.
89 bool empty() const { return unacked_packets_.empty(); }
90
91 // Returns the largest packet number that has been sent.
92 QuicPacketNumber largest_sent_packet() const { return largest_sent_packet_; }
93
QUICHE teama6ef0a62019-03-07 20:34:33 -050094 QuicPacketNumber largest_sent_largest_acked() const {
95 return largest_sent_largest_acked_;
96 }
97
98 // Returns the largest packet number that has been acked.
99 QuicPacketNumber largest_acked() const { return largest_acked_; }
100
101 // Returns the sum of bytes from all packets in flight.
102 QuicByteCount bytes_in_flight() const { return bytes_in_flight_; }
103
104 // Returns the smallest packet number of a serialized packet which has not
105 // been acked by the peer. If there are no unacked packets, returns 0.
106 QuicPacketNumber GetLeastUnacked() const;
107
108 // This can not be a QuicDeque since pointers into this are
109 // assumed to be stable.
110 typedef std::deque<QuicTransmissionInfo> UnackedPacketMap;
111
112 typedef UnackedPacketMap::const_iterator const_iterator;
113 typedef UnackedPacketMap::iterator iterator;
114
115 const_iterator begin() const { return unacked_packets_.begin(); }
116 const_iterator end() const { return unacked_packets_.end(); }
117 iterator begin() { return unacked_packets_.begin(); }
118 iterator end() { return unacked_packets_.end(); }
119
120 // Returns true if there are unacked packets that are in flight.
121 bool HasInFlightPackets() const;
122
123 // Returns the QuicTransmissionInfo associated with |packet_number|, which
124 // must be unacked.
125 const QuicTransmissionInfo& GetTransmissionInfo(
126 QuicPacketNumber packet_number) const;
127
128 // Returns mutable QuicTransmissionInfo associated with |packet_number|, which
129 // must be unacked.
130 QuicTransmissionInfo* GetMutableTransmissionInfo(
131 QuicPacketNumber packet_number);
132
133 // Returns the time that the last unacked packet was sent.
134 QuicTime GetLastPacketSentTime() const;
135
136 // Returns the time that the last unacked crypto packet was sent.
137 QuicTime GetLastCryptoPacketSentTime() const;
138
139 // Returns the number of unacked packets.
140 size_t GetNumUnackedPacketsDebugOnly() const;
141
142 // Returns true if there are multiple packets in flight.
143 bool HasMultipleInFlightPackets() const;
144
145 // Returns true if there are any pending crypto packets.
146 // TODO(fayang): Remove this method and call session_notifier_'s
147 // HasUnackedCryptoData() when session_decides_what_to_write_ is default true.
148 bool HasPendingCryptoPackets() const;
149
zhongyi1b2f7832019-06-14 13:31:34 -0700150 // Returns true if there is any unacked non-crypto stream data.
151 bool HasUnackedStreamData() const {
152 DCHECK(session_decides_what_to_write());
153 return session_notifier_->HasUnackedStreamData();
154 }
155
QUICHE teama6ef0a62019-03-07 20:34:33 -0500156 // Removes any retransmittable frames from this transmission or an associated
157 // transmission. It removes now useless transmissions, and disconnects any
158 // other packets from other transmissions.
159 void RemoveRetransmittability(QuicTransmissionInfo* info);
160
161 // Looks up the QuicTransmissionInfo by |packet_number| and calls
162 // RemoveRetransmittability.
163 void RemoveRetransmittability(QuicPacketNumber packet_number);
164
165 // Increases the largest acked. Any packets less or equal to
166 // |largest_acked| are discarded if they are only for the RTT purposes.
167 void IncreaseLargestAcked(QuicPacketNumber largest_acked);
168
169 // Called when |packet_number| gets acked. Maybe increase the largest acked of
fayang3eb82212019-04-16 12:05:46 -0700170 // |packet_number_space|.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500171 void MaybeUpdateLargestAckedOfPacketNumberSpace(
fayang3eb82212019-04-16 12:05:46 -0700172 PacketNumberSpace packet_number_space,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500173 QuicPacketNumber packet_number);
174
175 // Remove any packets no longer needed for retransmission, congestion, or
176 // RTT measurement purposes.
177 void RemoveObsoletePackets();
178
179 // Try to aggregate acked contiguous stream frames. For noncontiguous stream
180 // frames or control frames, notify the session notifier they get acked
181 // immediately.
182 void MaybeAggregateAckedStreamFrame(const QuicTransmissionInfo& info,
QUICHE team9467db02019-05-30 09:38:45 -0700183 QuicTime::Delta ack_delay,
184 QuicTime receive_timestamp);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500185
186 // Notify the session notifier of any stream data aggregated in
187 // aggregated_stream_frame_. No effect if the stream frame has an invalid
188 // stream id.
189 void NotifyAggregatedStreamFrameAcked(QuicTime::Delta ack_delay);
190
191 // Returns packet number space that |packet_number| belongs to. Please use
192 // GetPacketNumberSpace(EncryptionLevel) whenever encryption level is
193 // available.
194 PacketNumberSpace GetPacketNumberSpace(QuicPacketNumber packet_number) const;
195
196 // Returns packet number space of |encryption_level|.
197 PacketNumberSpace GetPacketNumberSpace(
198 EncryptionLevel encryption_level) const;
199
200 // Returns largest acked packet number of |packet_number_space|.
201 QuicPacketNumber GetLargestAckedOfPacketNumberSpace(
202 PacketNumberSpace packet_number_space) const;
203
204 // Returns largest sent retransmittable packet number of
205 // |packet_number_space|.
206 QuicPacketNumber GetLargestSentRetransmittableOfPacketNumberSpace(
207 PacketNumberSpace packet_number_space) const;
208
QUICHE teamc279cec2019-03-22 06:51:48 -0700209 // Returns largest sent packet number of |encryption_level|.
210 QuicPacketNumber GetLargestSentPacketOfPacketNumberSpace(
211 EncryptionLevel encryption_level) const;
212
QUICHE teama6ef0a62019-03-07 20:34:33 -0500213 // Called to start/stop letting session decide what to write.
214 void SetSessionDecideWhatToWrite(bool session_decides_what_to_write);
215
216 void SetSessionNotifier(SessionNotifierInterface* session_notifier);
217
QUICHE teamc279cec2019-03-22 06:51:48 -0700218 void EnableMultiplePacketNumberSpacesSupport();
219
QUICHE teama6ef0a62019-03-07 20:34:33 -0500220 bool session_decides_what_to_write() const {
221 return session_decides_what_to_write_;
222 }
223
QUICHE teama6ef0a62019-03-07 20:34:33 -0500224 Perspective perspective() const { return perspective_; }
225
QUICHE teamc279cec2019-03-22 06:51:48 -0700226 bool supports_multiple_packet_number_spaces() const {
227 return supports_multiple_packet_number_spaces_;
228 }
229
QUICHE teama6ef0a62019-03-07 20:34:33 -0500230 private:
231 friend class test::QuicUnackedPacketMapPeer;
232
233 // Called when a packet is retransmitted with a new packet number.
234 // |old_packet_number| will remain unacked, but will have no
235 // retransmittable data associated with it. Retransmittable frames will be
236 // transferred to |info| and all_transmissions will be populated.
237 void TransferRetransmissionInfo(QuicPacketNumber old_packet_number,
238 QuicPacketNumber new_packet_number,
239 TransmissionType transmission_type,
240 QuicTransmissionInfo* info);
241
242 // Returns true if packet may be useful for an RTT measurement.
243 bool IsPacketUsefulForMeasuringRtt(QuicPacketNumber packet_number,
244 const QuicTransmissionInfo& info) const;
245
246 // Returns true if packet may be useful for congestion control purposes.
247 bool IsPacketUsefulForCongestionControl(
248 const QuicTransmissionInfo& info) const;
249
250 // Returns true if packet may be associated with retransmittable data
251 // directly or through retransmissions.
252 bool IsPacketUsefulForRetransmittableData(
253 const QuicTransmissionInfo& info) const;
254
255 // Returns true if the packet no longer has a purpose in the map.
256 bool IsPacketUseless(QuicPacketNumber packet_number,
257 const QuicTransmissionInfo& info) const;
258
259 const Perspective perspective_;
260
261 QuicPacketNumber largest_sent_packet_;
QUICHE teamc279cec2019-03-22 06:51:48 -0700262 // Only used when supports_multiple_packet_number_spaces_ is true.
263 QuicPacketNumber largest_sent_packets_[NUM_PACKET_NUMBER_SPACES];
QUICHE teama6ef0a62019-03-07 20:34:33 -0500264 // The largest sent packet we expect to receive an ack for per packet number
fayangbf3d2862019-06-20 14:13:44 -0700265 // space.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500266 QuicPacketNumber
267 largest_sent_retransmittable_packets_[NUM_PACKET_NUMBER_SPACES];
268 // The largest sent largest_acked in an ACK frame.
269 QuicPacketNumber largest_sent_largest_acked_;
270 // The largest received largest_acked from an ACK frame.
271 QuicPacketNumber largest_acked_;
272 // The largest received largest_acked from ACK frame per packet number space.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500273 QuicPacketNumber largest_acked_packets_[NUM_PACKET_NUMBER_SPACES];
274
275 // Newly serialized retransmittable packets are added to this map, which
276 // contains owning pointers to any contained frames. If a packet is
277 // retransmitted, this map will contain entries for both the old and the new
278 // packet. The old packet's retransmittable frames entry will be nullptr,
279 // while the new packet's entry will contain the frames to retransmit.
280 // If the old packet is acked before the new packet, then the old entry will
281 // be removed from the map and the new entry's retransmittable frames will be
282 // set to nullptr.
283 UnackedPacketMap unacked_packets_;
284 // The packet at the 0th index of unacked_packets_.
285 QuicPacketNumber least_unacked_;
286
287 QuicByteCount bytes_in_flight_;
288 // Number of retransmittable crypto handshake packets.
289 size_t pending_crypto_packet_count_;
290
291 // Time that the last unacked crypto packet was sent.
292 QuicTime last_crypto_packet_sent_time_;
293
294 // Aggregates acked stream data across multiple acked sent packets to save CPU
295 // by reducing the number of calls to the session notifier.
296 QuicStreamFrame aggregated_stream_frame_;
297
298 // Receives notifications of frames being retransmitted or acknowledged.
299 SessionNotifierInterface* session_notifier_;
300
301 // If true, let session decides what to write.
302 bool session_decides_what_to_write_;
303
QUICHE teamc279cec2019-03-22 06:51:48 -0700304 // If true, supports multiple packet number spaces.
305 bool supports_multiple_packet_number_spaces_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500306};
307
308} // namespace quic
309
310#endif // QUICHE_QUIC_CORE_QUIC_UNACKED_PACKET_MAP_H_