| Index: net/quic/quic_sent_packet_manager.cc
|
| diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc
|
| index 3b6e9df0fde1ae9b62c0483b220fb45e4d346698..756768257372694df9fe59342ccf60a0ba2bce96 100644
|
| --- a/net/quic/quic_sent_packet_manager.cc
|
| +++ b/net/quic/quic_sent_packet_manager.cc
|
| @@ -99,6 +99,7 @@ QuicSentPacketManager::QuicSentPacketManager(
|
| enable_half_rtt_tail_loss_probe_(false),
|
| using_pacing_(false),
|
| use_new_rto_(false),
|
| + undo_pending_retransmits_(false),
|
| largest_newly_acked_(0),
|
| handshake_confirmed_(false) {}
|
|
|
| @@ -170,6 +171,10 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
|
| ContainsQuicTag(config.ReceivedConnectionOptions(), kATIM)) {
|
| loss_algorithm_.reset(new GeneralLossAlgorithm(kAdaptiveTime));
|
| }
|
| + if (FLAGS_quic_loss_recovery_use_largest_acked &&
|
| + config.HasClientSentConnectionOption(kUNDO, perspective_)) {
|
| + undo_pending_retransmits_ = true;
|
| + }
|
| if (config.HasReceivedSocketReceiveBuffer()) {
|
| receive_buffer_bytes_ =
|
| max(kMinSocketReceiveBuffer,
|
| @@ -258,6 +263,17 @@ void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame,
|
| consecutive_tlp_count_ = 0;
|
| consecutive_crypto_retransmission_count_ = 0;
|
| }
|
| + // TODO(ianswett): Consider replacing the pending_retransmissions_ with a
|
| + // fast way to retrieve the next pending retransmission, if there are any.
|
| + // A single packet number indicating all packets below that are lost should
|
| + // be all the state that is necessary.
|
| + while (undo_pending_retransmits_ && !pending_retransmissions_.empty() &&
|
| + pending_retransmissions_.front().first > largest_newly_acked_ &&
|
| + pending_retransmissions_.front().second == LOSS_RETRANSMISSION) {
|
| + // Cancel any pending retransmissions larger than largest_newly_acked_.
|
| + unacked_packets_.RestoreToInFlight(pending_retransmissions_.front().first);
|
| + pending_retransmissions_.erase(pending_retransmissions_.begin());
|
| + }
|
|
|
| if (debug_delegate_ != nullptr) {
|
| debug_delegate_->OnIncomingAck(ack_frame, ack_receive_time,
|
| @@ -328,6 +344,9 @@ void QuicSentPacketManager::HandleAckForSentPackets(
|
| // packet, then inform the caller.
|
| if (it->in_flight) {
|
| packets_acked_.push_back(std::make_pair(packet_number, it->bytes_sent));
|
| + } else if (FLAGS_quic_loss_recovery_use_largest_acked &&
|
| + !it->is_unackable) {
|
| + largest_newly_acked_ = packet_number;
|
| }
|
| MarkPacketHandled(packet_number, &(*it), ack_delay_time);
|
| }
|
| @@ -535,6 +554,9 @@ void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number,
|
|
|
| unacked_packets_.RemoveFromInFlight(info);
|
| unacked_packets_.RemoveRetransmittability(info);
|
| + if (FLAGS_quic_loss_recovery_use_largest_acked) {
|
| + info->is_unackable = true;
|
| + }
|
| }
|
|
|
| bool QuicSentPacketManager::IsUnacked(QuicPacketNumber packet_number) const {
|
|
|