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 #include "net/third_party/quiche/src/quic/core/quic_unacked_packet_map.h"
6 
7 #include <cstddef>
8 #include <limits>
9 #include <type_traits>
10 
11 #include "net/third_party/quiche/src/quic/core/quic_connection_stats.h"
12 #include "net/third_party/quiche/src/quic/core/quic_packet_number.h"
13 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
14 #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
15 #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
16 
17 namespace quic {
18 
19 namespace {
WillStreamFrameLengthSumWrapAround(QuicPacketLength lhs,QuicPacketLength rhs)20 bool WillStreamFrameLengthSumWrapAround(QuicPacketLength lhs,
21                                         QuicPacketLength rhs) {
22   static_assert(
23       std::is_unsigned<QuicPacketLength>::value,
24       "This function assumes QuicPacketLength is an unsigned integer type.");
25   return std::numeric_limits<QuicPacketLength>::max() - lhs < rhs;
26 }
27 
28 enum QuicFrameTypeBitfield : uint32_t {
29   kInvalidFrameBitfield = 0,
30   kPaddingFrameBitfield = 1,
31   kRstStreamFrameBitfield = 1 << 1,
32   kConnectionCloseFrameBitfield = 1 << 2,
33   kGoawayFrameBitfield = 1 << 3,
34   kWindowUpdateFrameBitfield = 1 << 4,
35   kBlockedFrameBitfield = 1 << 5,
36   kStopWaitingFrameBitfield = 1 << 6,
37   kPingFrameBitfield = 1 << 7,
38   kCryptoFrameBitfield = 1 << 8,
39   kHandshakeDoneFrameBitfield = 1 << 9,
40   kStreamFrameBitfield = 1 << 10,
41   kAckFrameBitfield = 1 << 11,
42   kMtuDiscoveryFrameBitfield = 1 << 12,
43   kNewConnectionIdFrameBitfield = 1 << 13,
44   kMaxStreamsFrameBitfield = 1 << 14,
45   kStreamsBlockedFrameBitfield = 1 << 15,
46   kPathResponseFrameBitfield = 1 << 16,
47   kPathChallengeFrameBitfield = 1 << 17,
48   kStopSendingFrameBitfield = 1 << 18,
49   kMessageFrameBitfield = 1 << 19,
50   kNewTokenFrameBitfield = 1 << 20,
51   kRetireConnectionIdFrameBitfield = 1 << 21,
52   kAckFrequencyFrameBitfield = 1 << 22,
53 };
54 
GetFrameTypeBitfield(QuicFrameType type)55 QuicFrameTypeBitfield GetFrameTypeBitfield(QuicFrameType type) {
56   switch (type) {
57     case PADDING_FRAME:
58       return kPaddingFrameBitfield;
59     case RST_STREAM_FRAME:
60       return kRstStreamFrameBitfield;
61     case CONNECTION_CLOSE_FRAME:
62       return kConnectionCloseFrameBitfield;
63     case GOAWAY_FRAME:
64       return kGoawayFrameBitfield;
65     case WINDOW_UPDATE_FRAME:
66       return kWindowUpdateFrameBitfield;
67     case BLOCKED_FRAME:
68       return kBlockedFrameBitfield;
69     case STOP_WAITING_FRAME:
70       return kStopWaitingFrameBitfield;
71     case PING_FRAME:
72       return kPingFrameBitfield;
73     case CRYPTO_FRAME:
74       return kCryptoFrameBitfield;
75     case HANDSHAKE_DONE_FRAME:
76       return kHandshakeDoneFrameBitfield;
77     case STREAM_FRAME:
78       return kStreamFrameBitfield;
79     case ACK_FRAME:
80       return kAckFrameBitfield;
81     case MTU_DISCOVERY_FRAME:
82       return kMtuDiscoveryFrameBitfield;
83     case NEW_CONNECTION_ID_FRAME:
84       return kNewConnectionIdFrameBitfield;
85     case MAX_STREAMS_FRAME:
86       return kMaxStreamsFrameBitfield;
87     case STREAMS_BLOCKED_FRAME:
88       return kStreamsBlockedFrameBitfield;
89     case PATH_RESPONSE_FRAME:
90       return kPathResponseFrameBitfield;
91     case PATH_CHALLENGE_FRAME:
92       return kPathChallengeFrameBitfield;
93     case STOP_SENDING_FRAME:
94       return kStopSendingFrameBitfield;
95     case MESSAGE_FRAME:
96       return kMessageFrameBitfield;
97     case NEW_TOKEN_FRAME:
98       return kNewTokenFrameBitfield;
99     case RETIRE_CONNECTION_ID_FRAME:
100       return kRetireConnectionIdFrameBitfield;
101     case ACK_FREQUENCY_FRAME:
102       return kAckFrequencyFrameBitfield;
103     case NUM_FRAME_TYPES:
104       QUIC_BUG << "Unexpected frame type";
105       return kInvalidFrameBitfield;
106   }
107   QUIC_BUG << "Unexpected frame type";
108   return kInvalidFrameBitfield;
109 }
110 
111 }  // namespace
112 
QuicUnackedPacketMap(Perspective perspective)113 QuicUnackedPacketMap::QuicUnackedPacketMap(Perspective perspective)
114     : perspective_(perspective),
115       least_unacked_(FirstSendingPacketNumber()),
116       bytes_in_flight_(0),
117       bytes_in_flight_per_packet_number_space_{0, 0, 0},
118       packets_in_flight_(0),
119       last_inflight_packet_sent_time_(QuicTime::Zero()),
120       last_inflight_packets_sent_time_{{QuicTime::Zero()},
121                                        {QuicTime::Zero()},
122                                        {QuicTime::Zero()}},
123       last_crypto_packet_sent_time_(QuicTime::Zero()),
124       session_notifier_(nullptr),
125       supports_multiple_packet_number_spaces_(false) {
126   if (use_circular_deque_) {
127     QUIC_RELOADABLE_FLAG_COUNT(quic_use_circular_deque_for_unacked_packets);
128   }
129 }
130 
~QuicUnackedPacketMap()131 QuicUnackedPacketMap::~QuicUnackedPacketMap() {
132   if (use_circular_deque_) {
133     for (QuicTransmissionInfo& transmission_info : unacked_packets_) {
134       DeleteFrames(&(transmission_info.retransmittable_frames));
135     }
136   } else {
137     for (QuicTransmissionInfo& transmission_info : unacked_packets_deque_) {
138       DeleteFrames(&(transmission_info.retransmittable_frames));
139     }
140   }
141 }
142 
AddSentPacket(SerializedPacket * mutable_packet,TransmissionType transmission_type,QuicTime sent_time,bool set_in_flight,bool measure_rtt)143 void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* mutable_packet,
144                                          TransmissionType transmission_type,
145                                          QuicTime sent_time,
146                                          bool set_in_flight,
147                                          bool measure_rtt) {
148   const SerializedPacket& packet = *mutable_packet;
149   QuicPacketNumber packet_number = packet.packet_number;
150   QuicPacketLength bytes_sent = packet.encrypted_length;
151   QUIC_BUG_IF(largest_sent_packet_.IsInitialized() &&
152               largest_sent_packet_ >= packet_number)
153       << "largest_sent_packet_: " << largest_sent_packet_
154       << ", packet_number: " << packet_number;
155   DCHECK_GE(packet_number, least_unacked_ + unacked_packets_size());
156   while (least_unacked_ + unacked_packets_size() < packet_number) {
157     unacked_packets_push_back(QuicTransmissionInfo());
158     unacked_packets_back().state = NEVER_SENT;
159   }
160 
161   const bool has_crypto_handshake = packet.has_crypto_handshake == IS_HANDSHAKE;
162   QuicTransmissionInfo info(packet.encryption_level, transmission_type,
163                             sent_time, bytes_sent, has_crypto_handshake,
164                             packet.has_ack_frequency);
165   info.largest_acked = packet.largest_acked;
166   largest_sent_largest_acked_.UpdateMax(packet.largest_acked);
167 
168   if (!measure_rtt) {
169     QUIC_BUG_IF(set_in_flight);
170     info.state = NOT_CONTRIBUTING_RTT;
171   }
172 
173   largest_sent_packet_ = packet_number;
174   if (set_in_flight) {
175     const PacketNumberSpace packet_number_space =
176         GetPacketNumberSpace(info.encryption_level);
177     bytes_in_flight_ += bytes_sent;
178     bytes_in_flight_per_packet_number_space_[packet_number_space] += bytes_sent;
179     ++packets_in_flight_;
180     info.in_flight = true;
181     largest_sent_retransmittable_packets_[packet_number_space] = packet_number;
182     last_inflight_packet_sent_time_ = sent_time;
183     last_inflight_packets_sent_time_[packet_number_space] = sent_time;
184   }
185   unacked_packets_push_back(info);
186   // Swap the retransmittable frames to avoid allocations.
187   // TODO(ianswett): Could use emplace_back when Chromium can.
188   if (has_crypto_handshake) {
189     last_crypto_packet_sent_time_ = sent_time;
190   }
191 
192   mutable_packet->retransmittable_frames.swap(
193       unacked_packets_back().retransmittable_frames);
194 }
195 
RemoveObsoletePackets()196 void QuicUnackedPacketMap::RemoveObsoletePackets() {
197   while (!unacked_packets_empty()) {
198     if (!IsPacketUseless(least_unacked_, unacked_packets_front())) {
199       break;
200     }
201     DeleteFrames(&unacked_packets_front().retransmittable_frames);
202     unacked_packets_pop_front();
203     ++least_unacked_;
204   }
205 }
206 
HasRetransmittableFrames(QuicPacketNumber packet_number) const207 bool QuicUnackedPacketMap::HasRetransmittableFrames(
208     QuicPacketNumber packet_number) const {
209   DCHECK_GE(packet_number, least_unacked_);
210   DCHECK_LT(packet_number, least_unacked_ + unacked_packets_size());
211   return HasRetransmittableFrames(
212       unacked_packets_at(packet_number - least_unacked_));
213 }
214 
HasRetransmittableFrames(const QuicTransmissionInfo & info) const215 bool QuicUnackedPacketMap::HasRetransmittableFrames(
216     const QuicTransmissionInfo& info) const {
217   if (!QuicUtils::IsAckable(info.state)) {
218     return false;
219   }
220 
221   for (const auto& frame : info.retransmittable_frames) {
222     if (session_notifier_->IsFrameOutstanding(frame)) {
223       return true;
224     }
225   }
226   return false;
227 }
228 
RemoveRetransmittability(QuicTransmissionInfo * info)229 void QuicUnackedPacketMap::RemoveRetransmittability(
230     QuicTransmissionInfo* info) {
231   DeleteFrames(&info->retransmittable_frames);
232   info->first_sent_after_loss.Clear();
233 }
234 
RemoveRetransmittability(QuicPacketNumber packet_number)235 void QuicUnackedPacketMap::RemoveRetransmittability(
236     QuicPacketNumber packet_number) {
237   DCHECK_GE(packet_number, least_unacked_);
238   DCHECK_LT(packet_number, least_unacked_ + unacked_packets_size());
239   QuicTransmissionInfo* info =
240       &unacked_packets_at(packet_number - least_unacked_);
241   RemoveRetransmittability(info);
242 }
243 
IncreaseLargestAcked(QuicPacketNumber largest_acked)244 void QuicUnackedPacketMap::IncreaseLargestAcked(
245     QuicPacketNumber largest_acked) {
246   DCHECK(!largest_acked_.IsInitialized() || largest_acked_ <= largest_acked);
247   largest_acked_ = largest_acked;
248 }
249 
MaybeUpdateLargestAckedOfPacketNumberSpace(PacketNumberSpace packet_number_space,QuicPacketNumber packet_number)250 void QuicUnackedPacketMap::MaybeUpdateLargestAckedOfPacketNumberSpace(
251     PacketNumberSpace packet_number_space,
252     QuicPacketNumber packet_number) {
253   largest_acked_packets_[packet_number_space].UpdateMax(packet_number);
254 }
255 
IsPacketUsefulForMeasuringRtt(QuicPacketNumber packet_number,const QuicTransmissionInfo & info) const256 bool QuicUnackedPacketMap::IsPacketUsefulForMeasuringRtt(
257     QuicPacketNumber packet_number,
258     const QuicTransmissionInfo& info) const {
259   // Packet can be used for RTT measurement if it may yet be acked as the
260   // largest observed packet by the receiver.
261   return QuicUtils::IsAckable(info.state) &&
262          (!largest_acked_.IsInitialized() || packet_number > largest_acked_) &&
263          info.state != NOT_CONTRIBUTING_RTT;
264 }
265 
IsPacketUsefulForCongestionControl(const QuicTransmissionInfo & info) const266 bool QuicUnackedPacketMap::IsPacketUsefulForCongestionControl(
267     const QuicTransmissionInfo& info) const {
268   // Packet contributes to congestion control if it is considered inflight.
269   return info.in_flight;
270 }
271 
IsPacketUsefulForRetransmittableData(const QuicTransmissionInfo & info) const272 bool QuicUnackedPacketMap::IsPacketUsefulForRetransmittableData(
273     const QuicTransmissionInfo& info) const {
274   // Wait for 1 RTT before giving up on the lost packet.
275   return info.first_sent_after_loss.IsInitialized() &&
276          (!largest_acked_.IsInitialized() ||
277           info.first_sent_after_loss > largest_acked_);
278 }
279 
IsPacketUseless(QuicPacketNumber packet_number,const QuicTransmissionInfo & info) const280 bool QuicUnackedPacketMap::IsPacketUseless(
281     QuicPacketNumber packet_number,
282     const QuicTransmissionInfo& info) const {
283   return !IsPacketUsefulForMeasuringRtt(packet_number, info) &&
284          !IsPacketUsefulForCongestionControl(info) &&
285          !IsPacketUsefulForRetransmittableData(info);
286 }
287 
IsUnacked(QuicPacketNumber packet_number) const288 bool QuicUnackedPacketMap::IsUnacked(QuicPacketNumber packet_number) const {
289   if (packet_number < least_unacked_ ||
290       packet_number >= least_unacked_ + unacked_packets_size()) {
291     return false;
292   }
293   return !IsPacketUseless(packet_number,
294                           unacked_packets_at(packet_number - least_unacked_));
295 }
296 
RemoveFromInFlight(QuicTransmissionInfo * info)297 void QuicUnackedPacketMap::RemoveFromInFlight(QuicTransmissionInfo* info) {
298   if (info->in_flight) {
299     QUIC_BUG_IF(bytes_in_flight_ < info->bytes_sent);
300     QUIC_BUG_IF(packets_in_flight_ == 0);
301     bytes_in_flight_ -= info->bytes_sent;
302     --packets_in_flight_;
303 
304     const PacketNumberSpace packet_number_space =
305         GetPacketNumberSpace(info->encryption_level);
306     if (bytes_in_flight_per_packet_number_space_[packet_number_space] <
307         info->bytes_sent) {
308       QUIC_BUG << "bytes_in_flight: "
309                << bytes_in_flight_per_packet_number_space_[packet_number_space]
310                << " is smaller than bytes_sent: " << info->bytes_sent
311                << " for packet number space: "
312                << PacketNumberSpaceToString(packet_number_space);
313       bytes_in_flight_per_packet_number_space_[packet_number_space] = 0;
314     } else {
315       bytes_in_flight_per_packet_number_space_[packet_number_space] -=
316           info->bytes_sent;
317     }
318     if (bytes_in_flight_per_packet_number_space_[packet_number_space] == 0) {
319       last_inflight_packets_sent_time_[packet_number_space] = QuicTime::Zero();
320     }
321 
322     info->in_flight = false;
323   }
324 }
325 
RemoveFromInFlight(QuicPacketNumber packet_number)326 void QuicUnackedPacketMap::RemoveFromInFlight(QuicPacketNumber packet_number) {
327   DCHECK_GE(packet_number, least_unacked_);
328   DCHECK_LT(packet_number, least_unacked_ + unacked_packets_size());
329   QuicTransmissionInfo* info =
330       &unacked_packets_at(packet_number - least_unacked_);
331   RemoveFromInFlight(info);
332 }
333 
334 QuicInlinedVector<QuicPacketNumber, 2>
NeuterUnencryptedPackets()335 QuicUnackedPacketMap::NeuterUnencryptedPackets() {
336   QuicInlinedVector<QuicPacketNumber, 2> neutered_packets;
337   QuicPacketNumber packet_number = GetLeastUnacked();
338   for (QuicUnackedPacketMap::iterator it = begin(); it != end();
339        ++it, ++packet_number) {
340     if (!it->retransmittable_frames.empty() &&
341         it->encryption_level == ENCRYPTION_INITIAL) {
342       QUIC_DVLOG(2) << "Neutering unencrypted packet " << packet_number;
343       // Once the connection swithes to forward secure, no unencrypted packets
344       // will be sent. The data has been abandoned in the cryto stream. Remove
345       // it from in flight.
346       RemoveFromInFlight(packet_number);
347       it->state = NEUTERED;
348       neutered_packets.push_back(packet_number);
349       // Notify session that the data has been delivered (but do not notify
350       // send algorithm).
351       // TODO(b/148868195): use NotifyFramesNeutered.
352       NotifyFramesAcked(*it, QuicTime::Delta::Zero(), QuicTime::Zero());
353       DCHECK(!HasRetransmittableFrames(*it));
354     }
355   }
356   DCHECK(!supports_multiple_packet_number_spaces_ ||
357          last_inflight_packets_sent_time_[INITIAL_DATA] == QuicTime::Zero());
358   return neutered_packets;
359 }
360 
361 QuicInlinedVector<QuicPacketNumber, 2>
NeuterHandshakePackets()362 QuicUnackedPacketMap::NeuterHandshakePackets() {
363   QuicInlinedVector<QuicPacketNumber, 2> neutered_packets;
364   QuicPacketNumber packet_number = GetLeastUnacked();
365   for (QuicUnackedPacketMap::iterator it = begin(); it != end();
366        ++it, ++packet_number) {
367     if (!it->retransmittable_frames.empty() &&
368         GetPacketNumberSpace(it->encryption_level) == HANDSHAKE_DATA) {
369       QUIC_DVLOG(2) << "Neutering handshake packet " << packet_number;
370       RemoveFromInFlight(packet_number);
371       // Notify session that the data has been delivered (but do not notify
372       // send algorithm).
373       it->state = NEUTERED;
374       neutered_packets.push_back(packet_number);
375       // TODO(b/148868195): use NotifyFramesNeutered.
376       NotifyFramesAcked(*it, QuicTime::Delta::Zero(), QuicTime::Zero());
377     }
378   }
379   DCHECK(!supports_multiple_packet_number_spaces() ||
380          last_inflight_packets_sent_time_[HANDSHAKE_DATA] == QuicTime::Zero());
381   return neutered_packets;
382 }
383 
HasInFlightPackets() const384 bool QuicUnackedPacketMap::HasInFlightPackets() const {
385   return bytes_in_flight_ > 0;
386 }
387 
GetTransmissionInfo(QuicPacketNumber packet_number) const388 const QuicTransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo(
389     QuicPacketNumber packet_number) const {
390   return unacked_packets_at(packet_number - least_unacked_);
391 }
392 
GetMutableTransmissionInfo(QuicPacketNumber packet_number)393 QuicTransmissionInfo* QuicUnackedPacketMap::GetMutableTransmissionInfo(
394     QuicPacketNumber packet_number) {
395   return &unacked_packets_at(packet_number - least_unacked_);
396 }
397 
GetLastInFlightPacketSentTime() const398 QuicTime QuicUnackedPacketMap::GetLastInFlightPacketSentTime() const {
399   return last_inflight_packet_sent_time_;
400 }
401 
GetLastCryptoPacketSentTime() const402 QuicTime QuicUnackedPacketMap::GetLastCryptoPacketSentTime() const {
403   return last_crypto_packet_sent_time_;
404 }
405 
GetNumUnackedPacketsDebugOnly() const406 size_t QuicUnackedPacketMap::GetNumUnackedPacketsDebugOnly() const {
407   size_t unacked_packet_count = 0;
408   QuicPacketNumber packet_number = least_unacked_;
409   for (auto it = begin(); it != end(); ++it, ++packet_number) {
410     if (!IsPacketUseless(packet_number, *it)) {
411       ++unacked_packet_count;
412     }
413   }
414   return unacked_packet_count;
415 }
416 
HasMultipleInFlightPackets() const417 bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const {
418   if (bytes_in_flight_ > kDefaultTCPMSS) {
419     return true;
420   }
421   size_t num_in_flight = 0;
422   for (auto it = rbegin(); it != rend(); ++it) {
423     if (it->in_flight) {
424       ++num_in_flight;
425     }
426     if (num_in_flight > 1) {
427       return true;
428     }
429   }
430   return false;
431 }
432 
HasPendingCryptoPackets() const433 bool QuicUnackedPacketMap::HasPendingCryptoPackets() const {
434   return session_notifier_->HasUnackedCryptoData();
435 }
436 
HasUnackedRetransmittableFrames() const437 bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const {
438   for (auto it = rbegin(); it != rend(); ++it) {
439     if (it->in_flight && HasRetransmittableFrames(*it)) {
440       return true;
441     }
442   }
443   return false;
444 }
445 
GetLeastUnacked() const446 QuicPacketNumber QuicUnackedPacketMap::GetLeastUnacked() const {
447   return least_unacked_;
448 }
449 
SetSessionNotifier(SessionNotifierInterface * session_notifier)450 void QuicUnackedPacketMap::SetSessionNotifier(
451     SessionNotifierInterface* session_notifier) {
452   session_notifier_ = session_notifier;
453 }
454 
NotifyFramesAcked(const QuicTransmissionInfo & info,QuicTime::Delta ack_delay,QuicTime receive_timestamp)455 bool QuicUnackedPacketMap::NotifyFramesAcked(const QuicTransmissionInfo& info,
456                                              QuicTime::Delta ack_delay,
457                                              QuicTime receive_timestamp) {
458   if (session_notifier_ == nullptr) {
459     return false;
460   }
461   bool new_data_acked = false;
462   for (const QuicFrame& frame : info.retransmittable_frames) {
463     if (session_notifier_->OnFrameAcked(frame, ack_delay, receive_timestamp)) {
464       new_data_acked = true;
465     }
466   }
467   return new_data_acked;
468 }
469 
NotifyFramesLost(const QuicTransmissionInfo & info,TransmissionType)470 void QuicUnackedPacketMap::NotifyFramesLost(const QuicTransmissionInfo& info,
471                                             TransmissionType /*type*/) {
472   for (const QuicFrame& frame : info.retransmittable_frames) {
473     session_notifier_->OnFrameLost(frame);
474   }
475 }
476 
RetransmitFrames(const QuicTransmissionInfo & info,TransmissionType type)477 void QuicUnackedPacketMap::RetransmitFrames(const QuicTransmissionInfo& info,
478                                             TransmissionType type) {
479   session_notifier_->RetransmitFrames(info.retransmittable_frames, type);
480 }
481 
MaybeAggregateAckedStreamFrame(const QuicTransmissionInfo & info,QuicTime::Delta ack_delay,QuicTime receive_timestamp)482 void QuicUnackedPacketMap::MaybeAggregateAckedStreamFrame(
483     const QuicTransmissionInfo& info,
484     QuicTime::Delta ack_delay,
485     QuicTime receive_timestamp) {
486   if (session_notifier_ == nullptr) {
487     return;
488   }
489   for (const auto& frame : info.retransmittable_frames) {
490     // Determine whether acked stream frame can be aggregated.
491     const bool can_aggregate =
492         frame.type == STREAM_FRAME &&
493         frame.stream_frame.stream_id == aggregated_stream_frame_.stream_id &&
494         frame.stream_frame.offset == aggregated_stream_frame_.offset +
495                                          aggregated_stream_frame_.data_length &&
496         // We would like to increment aggregated_stream_frame_.data_length by
497         // frame.stream_frame.data_length, so we need to make sure their sum is
498         // representable by QuicPacketLength, which is the type of the former.
499         !WillStreamFrameLengthSumWrapAround(
500             aggregated_stream_frame_.data_length,
501             frame.stream_frame.data_length);
502 
503     if (can_aggregate) {
504       // Aggregate stream frame.
505       aggregated_stream_frame_.data_length += frame.stream_frame.data_length;
506       aggregated_stream_frame_.fin = frame.stream_frame.fin;
507       if (aggregated_stream_frame_.fin) {
508         // Notify session notifier aggregated stream frame gets acked if fin is
509         // acked.
510         NotifyAggregatedStreamFrameAcked(ack_delay);
511       }
512       continue;
513     }
514 
515     NotifyAggregatedStreamFrameAcked(ack_delay);
516     if (frame.type != STREAM_FRAME || frame.stream_frame.fin) {
517       session_notifier_->OnFrameAcked(frame, ack_delay, receive_timestamp);
518       continue;
519     }
520 
521     // Delay notifying session notifier stream frame gets acked in case it can
522     // be aggregated with following acked ones.
523     aggregated_stream_frame_.stream_id = frame.stream_frame.stream_id;
524     aggregated_stream_frame_.offset = frame.stream_frame.offset;
525     aggregated_stream_frame_.data_length = frame.stream_frame.data_length;
526     aggregated_stream_frame_.fin = frame.stream_frame.fin;
527   }
528 }
529 
NotifyAggregatedStreamFrameAcked(QuicTime::Delta ack_delay)530 void QuicUnackedPacketMap::NotifyAggregatedStreamFrameAcked(
531     QuicTime::Delta ack_delay) {
532   if (aggregated_stream_frame_.stream_id == static_cast<QuicStreamId>(-1) ||
533       session_notifier_ == nullptr) {
534     // Aggregated stream frame is empty.
535     return;
536   }
537   // Note: there is no receive_timestamp for an aggregated stream frame.  The
538   // frames that are aggregated may not have been received at the same time.
539   session_notifier_->OnFrameAcked(QuicFrame(aggregated_stream_frame_),
540                                   ack_delay,
541                                   /*receive_timestamp=*/QuicTime::Zero());
542   // Clear aggregated stream frame.
543   aggregated_stream_frame_.stream_id = -1;
544 }
545 
GetPacketNumberSpace(QuicPacketNumber packet_number) const546 PacketNumberSpace QuicUnackedPacketMap::GetPacketNumberSpace(
547     QuicPacketNumber packet_number) const {
548   return GetPacketNumberSpace(
549       GetTransmissionInfo(packet_number).encryption_level);
550 }
551 
GetPacketNumberSpace(EncryptionLevel encryption_level) const552 PacketNumberSpace QuicUnackedPacketMap::GetPacketNumberSpace(
553     EncryptionLevel encryption_level) const {
554   if (supports_multiple_packet_number_spaces_) {
555     return QuicUtils::GetPacketNumberSpace(encryption_level);
556   }
557   if (perspective_ == Perspective::IS_CLIENT) {
558     return encryption_level == ENCRYPTION_INITIAL ? HANDSHAKE_DATA
559                                                   : APPLICATION_DATA;
560   }
561   return encryption_level == ENCRYPTION_FORWARD_SECURE ? APPLICATION_DATA
562                                                        : HANDSHAKE_DATA;
563 }
564 
GetLargestAckedOfPacketNumberSpace(PacketNumberSpace packet_number_space) const565 QuicPacketNumber QuicUnackedPacketMap::GetLargestAckedOfPacketNumberSpace(
566     PacketNumberSpace packet_number_space) const {
567   if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
568     QUIC_BUG << "Invalid packet number space: " << packet_number_space;
569     return QuicPacketNumber();
570   }
571   return largest_acked_packets_[packet_number_space];
572 }
573 
GetLastInFlightPacketSentTime(PacketNumberSpace packet_number_space) const574 QuicTime QuicUnackedPacketMap::GetLastInFlightPacketSentTime(
575     PacketNumberSpace packet_number_space) const {
576   if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
577     QUIC_BUG << "Invalid packet number space: " << packet_number_space;
578     return QuicTime::Zero();
579   }
580   return last_inflight_packets_sent_time_[packet_number_space];
581 }
582 
583 QuicPacketNumber
GetLargestSentRetransmittableOfPacketNumberSpace(PacketNumberSpace packet_number_space) const584 QuicUnackedPacketMap::GetLargestSentRetransmittableOfPacketNumberSpace(
585     PacketNumberSpace packet_number_space) const {
586   if (packet_number_space >= NUM_PACKET_NUMBER_SPACES) {
587     QUIC_BUG << "Invalid packet number space: " << packet_number_space;
588     return QuicPacketNumber();
589   }
590   return largest_sent_retransmittable_packets_[packet_number_space];
591 }
592 
593 const QuicTransmissionInfo*
GetFirstInFlightTransmissionInfo() const594 QuicUnackedPacketMap::GetFirstInFlightTransmissionInfo() const {
595   DCHECK(HasInFlightPackets());
596   for (auto it = begin(); it != end(); ++it) {
597     if (it->in_flight) {
598       return &(*it);
599     }
600   }
601   DCHECK(false);
602   return nullptr;
603 }
604 
605 const QuicTransmissionInfo*
GetFirstInFlightTransmissionInfoOfSpace(PacketNumberSpace packet_number_space) const606 QuicUnackedPacketMap::GetFirstInFlightTransmissionInfoOfSpace(
607     PacketNumberSpace packet_number_space) const {
608   // TODO(fayang): Optimize this part if arm 1st PTO with first in flight sent
609   // time works.
610   for (auto it = begin(); it != end(); ++it) {
611     if (it->in_flight &&
612         GetPacketNumberSpace(it->encryption_level) == packet_number_space) {
613       return &(*it);
614     }
615   }
616   return nullptr;
617 }
618 
EnableMultiplePacketNumberSpacesSupport()619 void QuicUnackedPacketMap::EnableMultiplePacketNumberSpacesSupport() {
620   if (supports_multiple_packet_number_spaces_) {
621     QUIC_BUG << "Multiple packet number spaces has already been enabled";
622     return;
623   }
624   if (largest_sent_packet_.IsInitialized()) {
625     QUIC_BUG << "Try to enable multiple packet number spaces support after any "
626                 "packet has been sent.";
627     return;
628   }
629 
630   supports_multiple_packet_number_spaces_ = true;
631 }
632 
GetLastPacketContent() const633 int32_t QuicUnackedPacketMap::GetLastPacketContent() const {
634   if (empty()) {
635     // Use -1 to distinguish with packets with no retransmittable frames nor
636     // acks.
637     return -1;
638   }
639   int32_t content = 0;
640   const QuicTransmissionInfo& last_packet = unacked_packets_back();
641   for (const auto& frame : last_packet.retransmittable_frames) {
642     content |= GetFrameTypeBitfield(frame.type);
643   }
644   if (last_packet.largest_acked.IsInitialized()) {
645     content |= GetFrameTypeBitfield(ACK_FRAME);
646   }
647   return content;
648 }
649 
650 }  // namespace quic
651