1 // Copyright 2013 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.
5 #include "net/quic/quic_sent_packet_manager.h"
7 #include "base/logging.h"
8 #include "base/stl_util.h"
12 // TODO(rtenneti): Remove this.
13 // Do not flip this flag until the flakiness of the
14 // net/tools/quic/end_to_end_test is fixed.
15 // If true, then QUIC connections will track the retransmission history of a
16 // packet so that an ack of a previous transmission will ack the data of all
17 // other transmissions.
18 bool FLAGS_track_retransmission_history
= false;
22 #define ENDPOINT (is_server_ ? "Server: " : " Client: ")
24 QuicSentPacketManager::HelperInterface::~HelperInterface() {
27 QuicSentPacketManager::QuicSentPacketManager(bool is_server
,
28 HelperInterface
* helper
)
29 : is_server_(is_server
),
33 QuicSentPacketManager::~QuicSentPacketManager() {
34 STLDeleteValues(&unacked_packets_
);
35 while (!previous_transmissions_map_
.empty()) {
36 SequenceNumberSet
* previous_transmissions
=
37 previous_transmissions_map_
.begin()->second
;
38 for (SequenceNumberSet::const_iterator it
= previous_transmissions
->begin();
39 it
!= previous_transmissions
->end(); ++it
) {
40 DCHECK(ContainsKey(previous_transmissions_map_
, *it
));
41 previous_transmissions_map_
.erase(*it
);
43 delete previous_transmissions
;
47 void QuicSentPacketManager::OnSerializedPacket(
48 const SerializedPacket
& serialized_packet
, QuicTime serialized_time
) {
49 if (serialized_packet
.packet
->is_fec_packet()) {
50 DCHECK(!serialized_packet
.retransmittable_frames
);
51 unacked_fec_packets_
.insert(make_pair(
52 serialized_packet
.sequence_number
, serialized_time
));
56 if (serialized_packet
.retransmittable_frames
== NULL
) {
57 // Don't track ack/congestion feedback packets.
61 DCHECK(unacked_packets_
.empty() ||
62 unacked_packets_
.rbegin()->first
<
63 serialized_packet
.sequence_number
);
64 unacked_packets_
[serialized_packet
.sequence_number
] =
65 serialized_packet
.retransmittable_frames
;
66 retransmission_map_
[serialized_packet
.sequence_number
] =
67 RetransmissionInfo(serialized_packet
.sequence_number
,
68 serialized_packet
.sequence_number_length
);
71 void QuicSentPacketManager::OnRetransmittedPacket(
72 QuicPacketSequenceNumber old_sequence_number
,
73 QuicPacketSequenceNumber new_sequence_number
) {
74 DCHECK(ContainsKey(unacked_packets_
, old_sequence_number
));
75 DCHECK(ContainsKey(retransmission_map_
, old_sequence_number
));
76 DCHECK(ContainsKey(pending_retransmissions_
, old_sequence_number
));
77 DCHECK(unacked_packets_
.empty() ||
78 unacked_packets_
.rbegin()->first
< new_sequence_number
);
80 pending_retransmissions_
.erase(old_sequence_number
);
82 RetransmissionInfo
retransmission_info(
83 new_sequence_number
, GetSequenceNumberLength(old_sequence_number
));
84 retransmission_info
.number_retransmissions
=
85 retransmission_map_
[old_sequence_number
].number_retransmissions
+ 1;
86 retransmission_map_
.erase(old_sequence_number
);
87 retransmission_map_
[new_sequence_number
] = retransmission_info
;
89 RetransmittableFrames
* frames
= unacked_packets_
[old_sequence_number
];
91 if (FLAGS_track_retransmission_history
) {
92 // We keep the old packet in the unacked packet list until it, or one of
93 // the retransmissions of it are acked.
94 unacked_packets_
[old_sequence_number
] = NULL
;
96 unacked_packets_
.erase(old_sequence_number
);
98 unacked_packets_
[new_sequence_number
] = frames
;
100 if (!FLAGS_track_retransmission_history
) {
103 // Keep track of all sequence numbers that this packet
104 // has been transmitted as.
105 SequenceNumberSet
* previous_transmissions
;
106 PreviousTransmissionMap::iterator it
=
107 previous_transmissions_map_
.find(old_sequence_number
);
108 if (it
== previous_transmissions_map_
.end()) {
109 // This is the first retransmission of this packet, so create a new entry.
110 previous_transmissions
= new SequenceNumberSet
;
111 previous_transmissions_map_
[old_sequence_number
] = previous_transmissions
;
112 previous_transmissions
->insert(old_sequence_number
);
114 // Otherwise, use the existing entry.
115 previous_transmissions
= it
->second
;
117 previous_transmissions
->insert(new_sequence_number
);
118 previous_transmissions_map_
[new_sequence_number
] = previous_transmissions
;
120 DCHECK(HasRetransmittableFrames(new_sequence_number
));
123 void QuicSentPacketManager::OnIncomingAck(
124 const ReceivedPacketInfo
& received_info
,
125 bool is_truncated_ack
,
126 SequenceNumberSet
* acked_packets
) {
127 HandleAckForSentPackets(received_info
, is_truncated_ack
, acked_packets
);
128 HandleAckForSentFecPackets(received_info
, acked_packets
);
131 void QuicSentPacketManager::DiscardUnackedPacket(
132 QuicPacketSequenceNumber sequence_number
) {
133 MarkPacketReceivedByPeer(sequence_number
);
136 void QuicSentPacketManager::HandleAckForSentPackets(
137 const ReceivedPacketInfo
& received_info
,
138 bool is_truncated_ack
,
139 SequenceNumberSet
* acked_packets
) {
140 // Go through the packets we have not received an ack for and see if this
141 // incoming_ack shows they've been seen by the peer.
142 UnackedPacketMap::iterator it
= unacked_packets_
.begin();
143 while (it
!= unacked_packets_
.end()) {
144 QuicPacketSequenceNumber sequence_number
= it
->first
;
145 if (sequence_number
> received_info
.largest_observed
) {
146 // These are very new sequence_numbers.
150 if (!IsAwaitingPacket(received_info
, sequence_number
)) {
151 // Packet was acked, so remove it from our unacked packet list.
152 DVLOG(1) << ENDPOINT
<<"Got an ack for packet " << sequence_number
;
153 // If data is associated with the most recent transmission of this
154 // packet, then inform the caller.
155 QuicPacketSequenceNumber most_recent_transmission
=
156 GetMostRecentTransmission(sequence_number
);
157 if (HasRetransmittableFrames(most_recent_transmission
)) {
158 acked_packets
->insert(most_recent_transmission
);
160 it
= MarkPacketReceivedByPeer(sequence_number
);
164 // The peer got packets after this sequence number. This is an explicit
167 // TODO(rch): move this to the congestion manager, and fix the logic.
168 // This is a packet which we planned on retransmitting and has not been
169 // seen at the time of this ack being sent out. See if it's our new
170 // lowest unacked packet.
171 DVLOG(1) << ENDPOINT
<< "still missing packet " << sequence_number
;
173 RetransmissionMap::iterator retransmission_it
=
174 retransmission_map_
.find(sequence_number
);
175 if (retransmission_it
== retransmission_map_
.end()) {
178 size_t nack_count
= ++(retransmission_it
->second
.number_nacks
);
179 helper_
->OnPacketNacked(sequence_number
, nack_count
);
182 // If we have received a trunacted ack, then we need to
183 // clear out some previous transmissions to allow the peer
184 // to actually ACK new packets.
185 if (is_truncated_ack
) {
186 size_t num_to_clear
= received_info
.missing_packets
.size() / 2;
187 UnackedPacketMap::iterator it
= unacked_packets_
.begin();
188 while (it
!= unacked_packets_
.end() && num_to_clear
> 0) {
189 QuicPacketSequenceNumber sequence_number
= it
->first
;
191 // If this is not a previous transmission then there is no point
192 // in clearing out any further packets, because it will not
193 // affect the high water mark.
194 if (!IsPreviousTransmission(sequence_number
)) {
198 DCHECK(ContainsKey(previous_transmissions_map_
, sequence_number
));
199 DCHECK(!ContainsKey(retransmission_map_
, sequence_number
));
200 DCHECK(!HasRetransmittableFrames(sequence_number
));
201 unacked_packets_
.erase(sequence_number
);
202 SequenceNumberSet
* previous_transmissions
=
203 previous_transmissions_map_
[sequence_number
];
204 previous_transmissions_map_
.erase(sequence_number
);
205 previous_transmissions
->erase(sequence_number
);
206 if (previous_transmissions
->size() == 1) {
207 previous_transmissions_map_
.erase(*previous_transmissions
->begin());
208 delete previous_transmissions
;
215 bool QuicSentPacketManager::HasRetransmittableFrames(
216 QuicPacketSequenceNumber sequence_number
) const {
217 if (!ContainsKey(unacked_packets_
, sequence_number
)) {
221 return unacked_packets_
.find(sequence_number
)->second
!= NULL
;
224 bool QuicSentPacketManager::MarkForRetransmission(
225 QuicPacketSequenceNumber sequence_number
,
226 TransmissionType transmission_type
) {
227 DCHECK(ContainsKey(unacked_packets_
, sequence_number
));
228 if (!HasRetransmittableFrames(sequence_number
)) {
231 // If it's already in the retransmission map, don't add it again, just let
232 // the prior retransmission request win out.
233 if (ContainsKey(pending_retransmissions_
, sequence_number
)) {
237 pending_retransmissions_
[sequence_number
] = transmission_type
;
241 bool QuicSentPacketManager::HasPendingRetransmissions() const {
242 return !pending_retransmissions_
.empty();
245 QuicSentPacketManager::PendingRetransmission
246 QuicSentPacketManager::NextPendingRetransmission() {
247 DCHECK(!pending_retransmissions_
.empty());
248 QuicPacketSequenceNumber sequence_number
=
249 pending_retransmissions_
.begin()->first
;
250 DCHECK(ContainsKey(unacked_packets_
, sequence_number
));
251 DCHECK(unacked_packets_
[sequence_number
]);
253 return PendingRetransmission(sequence_number
,
254 pending_retransmissions_
.begin()->second
,
255 GetRetransmittableFrames(sequence_number
),
256 GetSequenceNumberLength(sequence_number
));
259 bool QuicSentPacketManager::IsPreviousTransmission(
260 QuicPacketSequenceNumber sequence_number
) const {
261 DCHECK(ContainsKey(unacked_packets_
, sequence_number
));
263 PreviousTransmissionMap::const_iterator it
=
264 previous_transmissions_map_
.find(sequence_number
);
265 if (it
== previous_transmissions_map_
.end()) {
269 SequenceNumberSet
* previous_transmissions
= it
->second
;
270 DCHECK(!previous_transmissions
->empty());
271 return *previous_transmissions
->rbegin() != sequence_number
;
274 QuicPacketSequenceNumber
QuicSentPacketManager::GetMostRecentTransmission(
275 QuicPacketSequenceNumber sequence_number
) const {
276 DCHECK(ContainsKey(unacked_packets_
, sequence_number
));
278 PreviousTransmissionMap::const_iterator it
=
279 previous_transmissions_map_
.find(sequence_number
);
280 if (it
== previous_transmissions_map_
.end()) {
281 return sequence_number
;
284 SequenceNumberSet
* previous_transmissions
=
285 previous_transmissions_map_
.find(sequence_number
)->second
;
286 DCHECK(!previous_transmissions
->empty());
287 return *previous_transmissions
->rbegin();
290 QuicSentPacketManager::UnackedPacketMap::iterator
291 QuicSentPacketManager::MarkPacketReceivedByPeer(
292 QuicPacketSequenceNumber sequence_number
) {
293 DCHECK(ContainsKey(unacked_packets_
, sequence_number
));
294 UnackedPacketMap::iterator next_unacked
=
295 unacked_packets_
.find(sequence_number
);
298 // If this packet has never been retransmitted, then simply drop it.
299 if (!ContainsKey(previous_transmissions_map_
, sequence_number
)) {
300 DiscardPacket(sequence_number
);
304 SequenceNumberSet
* previous_transmissions
=
305 previous_transmissions_map_
.find(sequence_number
)->second
;
306 SequenceNumberSet::reverse_iterator previous_transmissions_it
307 = previous_transmissions
->rbegin();
308 DCHECK(previous_transmissions_it
!= previous_transmissions
->rend());
310 QuicPacketSequenceNumber new_packet
= *previous_transmissions_it
;
311 bool is_new_packet
= new_packet
== sequence_number
;
313 DiscardPacket(new_packet
);
315 if (next_unacked
->first
== new_packet
) {
318 // If we have received an ack for a previous transmission of a packet,
319 // we want to keep the "new" transmission of the packet unacked,
320 // but prevent the data from being retransmitted.
321 delete unacked_packets_
[new_packet
];
322 unacked_packets_
[new_packet
] = NULL
;
323 pending_retransmissions_
.erase(new_packet
);
325 previous_transmissions_map_
.erase(new_packet
);
327 // Clear out information all previous transmissions.
328 ++previous_transmissions_it
;
329 while (previous_transmissions_it
!= previous_transmissions
->rend()) {
330 QuicPacketSequenceNumber previous_transmission
= *previous_transmissions_it
;
331 ++previous_transmissions_it
;
332 DCHECK(ContainsKey(previous_transmissions_map_
, previous_transmission
));
333 previous_transmissions_map_
.erase(previous_transmission
);
334 if (next_unacked
!= unacked_packets_
.end() &&
335 next_unacked
->first
== previous_transmission
) {
338 DiscardPacket(previous_transmission
);
341 delete previous_transmissions
;
343 next_unacked
= unacked_packets_
.begin();
344 while (next_unacked
!= unacked_packets_
.end() &&
345 next_unacked
->first
< sequence_number
) {
351 void QuicSentPacketManager::DiscardPacket(
352 QuicPacketSequenceNumber sequence_number
) {
353 UnackedPacketMap::iterator unacked_it
=
354 unacked_packets_
.find(sequence_number
);
355 // Packet was not meant to be retransmitted.
356 if (unacked_it
== unacked_packets_
.end()) {
357 DCHECK(!ContainsKey(retransmission_map_
, sequence_number
));
361 // Delete the unacked packet.
362 delete unacked_it
->second
;
363 unacked_packets_
.erase(unacked_it
);
364 retransmission_map_
.erase(sequence_number
);
365 pending_retransmissions_
.erase(sequence_number
);
369 void QuicSentPacketManager::HandleAckForSentFecPackets(
370 const ReceivedPacketInfo
& received_info
,
371 SequenceNumberSet
* acked_packets
) {
372 UnackedFecPacketMap::iterator it
= unacked_fec_packets_
.begin();
373 while (it
!= unacked_fec_packets_
.end()) {
374 QuicPacketSequenceNumber sequence_number
= it
->first
;
375 if (sequence_number
> received_info
.largest_observed
) {
379 if (!IsAwaitingPacket(received_info
, sequence_number
)) {
380 DVLOG(1) << ENDPOINT
<< "Got an ack for fec packet: " << sequence_number
;
381 acked_packets
->insert(sequence_number
);
382 unacked_fec_packets_
.erase(it
++);
384 // TODO(rch): treat these packets more consistently. They should
385 // be subject to NACK and RTO based loss. (Thought obviously, they
386 // should not be retransmitted.)
387 DVLOG(1) << ENDPOINT
<< "Still missing ack for fec packet: "
394 void QuicSentPacketManager::DiscardFecPacket(
395 QuicPacketSequenceNumber sequence_number
) {
396 DCHECK(ContainsKey(unacked_fec_packets_
, sequence_number
));
397 unacked_fec_packets_
.erase(sequence_number
);
400 bool QuicSentPacketManager::IsRetransmission(
401 QuicPacketSequenceNumber sequence_number
) const {
402 DCHECK(HasRetransmittableFrames(sequence_number
));
403 RetransmissionMap::const_iterator it
=
404 retransmission_map_
.find(sequence_number
);
405 return it
!= retransmission_map_
.end() &&
406 it
->second
.number_retransmissions
> 0;
409 size_t QuicSentPacketManager::GetRetransmissionCount(
410 QuicPacketSequenceNumber sequence_number
) const {
411 DCHECK(HasRetransmittableFrames(sequence_number
));
412 DCHECK(ContainsKey(retransmission_map_
, sequence_number
));
413 RetransmissionMap::const_iterator it
=
414 retransmission_map_
.find(sequence_number
);
415 return it
->second
.number_retransmissions
;
418 bool QuicSentPacketManager::IsUnacked(
419 QuicPacketSequenceNumber sequence_number
) const {
420 return ContainsKey(unacked_packets_
, sequence_number
);
423 bool QuicSentPacketManager::IsFecUnacked(
424 QuicPacketSequenceNumber sequence_number
) const {
425 return ContainsKey(unacked_fec_packets_
, sequence_number
);
428 const RetransmittableFrames
& QuicSentPacketManager::GetRetransmittableFrames(
429 QuicPacketSequenceNumber sequence_number
) const {
430 DCHECK(ContainsKey(unacked_packets_
, sequence_number
));
431 DCHECK(ContainsKey(retransmission_map_
, sequence_number
));
433 return *unacked_packets_
.find(sequence_number
)->second
;
436 QuicSequenceNumberLength
QuicSentPacketManager::GetSequenceNumberLength(
437 QuicPacketSequenceNumber sequence_number
) const {
438 DCHECK(ContainsKey(unacked_packets_
, sequence_number
));
439 DCHECK(ContainsKey(retransmission_map_
, sequence_number
));
441 return retransmission_map_
.find(
442 sequence_number
)->second
.sequence_number_length
;
445 QuicTime
QuicSentPacketManager::GetFecSentTime(
446 QuicPacketSequenceNumber sequence_number
) const {
447 DCHECK(ContainsKey(unacked_fec_packets_
, sequence_number
));
449 return unacked_fec_packets_
.find(sequence_number
)->second
;
452 bool QuicSentPacketManager::HasUnackedPackets() const {
453 return !unacked_packets_
.empty();
456 size_t QuicSentPacketManager::GetNumUnackedPackets() const {
457 return unacked_packets_
.size();
460 bool QuicSentPacketManager::HasUnackedFecPackets() const {
461 return !unacked_fec_packets_
.empty();
464 QuicPacketSequenceNumber
465 QuicSentPacketManager::GetLeastUnackedSentPacket() const {
466 if (unacked_packets_
.empty()) {
467 // If there are no unacked packets, set the least unacked packet to
468 // the sequence number of the next packet sent.
469 return helper_
->GetNextPacketSequenceNumber();
472 return unacked_packets_
.begin()->first
;
475 QuicPacketSequenceNumber
476 QuicSentPacketManager::GetLeastUnackedFecPacket() const {
477 if (unacked_fec_packets_
.empty()) {
478 // If there are no unacked packets, set the least unacked packet to
479 // the sequence number of the next packet sent.
480 return helper_
->GetNextPacketSequenceNumber();
483 return unacked_fec_packets_
.begin()->first
;
486 SequenceNumberSet
QuicSentPacketManager::GetUnackedPackets() const {
487 SequenceNumberSet unacked_packets
;
488 for (UnackedPacketMap::const_iterator it
= unacked_packets_
.begin();
489 it
!= unacked_packets_
.end(); ++it
) {
490 unacked_packets
.insert(it
->first
);
492 return unacked_packets
;