| 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 &&
|
|
|