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 8c41b9cf167cdc5aa6483b96841531df6f9af824..806297e357554e4631f12ad8c00b7b07f949af20 100644 |
--- a/net/quic/quic_sent_packet_manager.cc |
+++ b/net/quic/quic_sent_packet_manager.cc |
@@ -467,6 +467,7 @@ bool QuicSentPacketManager::OnPacketSent( |
void QuicSentPacketManager::OnRetransmissionTimeout() { |
DCHECK(unacked_packets_.HasInFlightPackets()); |
+ DCHECK(!pending_tlp_transmission_); |
// Handshake retransmission, timer based loss detection, TLP, and RTO are |
// implemented with a single alarm. The handshake alarm is set when the |
// handshake has not completed, the loss alarm is set when the loss detection |
@@ -488,8 +489,10 @@ void QuicSentPacketManager::OnRetransmissionTimeout() { |
// If no tail loss probe can be sent, because there are no retransmittable |
// packets, execute a conventional RTO to abandon old packets. |
++stats_->tlp_count; |
+ ++consecutive_tlp_count_; |
pending_tlp_transmission_ = true; |
- RetransmitOldestPacket(); |
+ // TLPs prefer sending new data instead of retransmitting data, so |
+ // give the connection a chance to write before completing the TLP. |
return; |
case RTO_MODE: |
++stats_->rto_count; |
@@ -520,9 +523,10 @@ void QuicSentPacketManager::RetransmitCryptoPackets() { |
DCHECK(packet_retransmitted) << "No crypto packets found to retransmit."; |
} |
-void QuicSentPacketManager::RetransmitOldestPacket() { |
- DCHECK_EQ(TLP_MODE, GetRetransmissionMode()); |
- ++consecutive_tlp_count_; |
+bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() { |
+ if (!pending_tlp_transmission_) { |
+ return false; |
+ } |
for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
it != unacked_packets_.end(); ++it) { |
QuicPacketSequenceNumber sequence_number = it->first; |
@@ -533,10 +537,11 @@ void QuicSentPacketManager::RetransmitOldestPacket() { |
} |
DCHECK_NE(IS_HANDSHAKE, frames->HasCryptoHandshake()); |
MarkForRetransmission(sequence_number, TLP_RETRANSMISSION); |
- return; |
+ return true; |
} |
DLOG(FATAL) |
<< "No retransmittable packets, so RetransmitOldestPacket failed."; |
+ return false; |
} |
void QuicSentPacketManager::RetransmitAllPackets() { |
@@ -671,8 +676,9 @@ const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const { |
} |
const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { |
- // Don't set the timer if there are no packets in flight. |
- if (!unacked_packets_.HasInFlightPackets()) { |
+ // Don't set the timer if there are no packets in flight or we've already |
+ // queued a tlp transmission and it hasn't been sent yet. |
+ if (!unacked_packets_.HasInFlightPackets() || pending_tlp_transmission_) { |
return QuicTime::Zero(); |
} |
switch (GetRetransmissionMode()) { |