Index: net/quic/quic_unacked_packet_map.cc |
diff --git a/net/quic/quic_unacked_packet_map.cc b/net/quic/quic_unacked_packet_map.cc |
index 2f971ee5c302331dd7d5ed36206b509d4d931d6f..3bba773681cfb46f769f988a4f5912c55f72d2cb 100644 |
--- a/net/quic/quic_unacked_packet_map.cc |
+++ b/net/quic/quic_unacked_packet_map.cc |
@@ -95,16 +95,24 @@ void QuicUnackedPacketMap::OnRetransmittedPacket( |
old_info->all_transmissions = NULL; |
} |
} |
- if (transmission_info->all_transmissions == NULL) { |
- transmission_info->all_transmissions = new SequenceNumberList(); |
- transmission_info->all_transmissions->push_back(old_sequence_number); |
+ // Don't link old transmissions to new ones when version or |
+ // encryption changes. |
+ if (transmission_type == ALL_INITIAL_RETRANSMISSION || |
+ transmission_type == ALL_UNACKED_RETRANSMISSION) { |
+ RemoveAckability(transmission_info); |
+ } else { |
+ if (transmission_info->all_transmissions == NULL) { |
+ transmission_info->all_transmissions = new SequenceNumberList(); |
+ transmission_info->all_transmissions->push_back(old_sequence_number); |
+ } |
+ transmission_info->all_transmissions->push_back(new_sequence_number); |
} |
- transmission_info->all_transmissions->push_back(new_sequence_number); |
unacked_packets_.push_back( |
TransmissionInfo(frames, |
transmission_info->sequence_number_length, |
transmission_type, |
transmission_info->all_transmissions)); |
+ RemoveObsoletePackets(); |
} |
void QuicUnackedPacketMap::ClearAllPreviousRetransmissions() { |
@@ -179,6 +187,23 @@ void QuicUnackedPacketMap::RemoveRetransmittability( |
delete all_transmissions; |
} |
+void QuicUnackedPacketMap::RemoveAckability(TransmissionInfo* info) { |
+ DCHECK(info->retransmittable_frames == NULL); |
+ info->is_unackable = true; |
+ SequenceNumberList* all_transmissions = info->all_transmissions; |
+ if (all_transmissions == NULL) { |
+ return; |
+ } |
+ for (SequenceNumberList::const_iterator it = all_transmissions->begin(); |
+ it != all_transmissions->end(); ++it) { |
+ TransmissionInfo* transmission_info = |
+ &unacked_packets_[*it - least_unacked_]; |
+ transmission_info->all_transmissions = NULL; |
+ transmission_info->is_unackable = true; |
+ } |
+ delete all_transmissions; |
+} |
+ |
void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames( |
TransmissionInfo* transmission_info) { |
if (transmission_info->retransmittable_frames != NULL) { |
@@ -209,7 +234,8 @@ bool QuicUnackedPacketMap::IsPacketUseless( |
bool QuicUnackedPacketMap::IsPacketRemovable( |
QuicPacketSequenceNumber sequence_number, |
const TransmissionInfo& info) const { |
- return (sequence_number <= largest_observed_ || |
+ return (info.is_unackable || |
+ sequence_number <= largest_observed_ || |
unacked_packets_.size() > kMaxTcpCongestionWindow) && |
!info.in_flight && |
info.retransmittable_frames == NULL && |