| 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
|
| deleted file mode 100644
|
| index 25e2a8afaf3b62561d7f4bad79c3fb63c4ff818a..0000000000000000000000000000000000000000
|
| --- a/net/quic/quic_unacked_packet_map.cc
|
| +++ /dev/null
|
| @@ -1,409 +0,0 @@
|
| -// Copyright 2014 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/quic/quic_unacked_packet_map.h"
|
| -
|
| -#include "base/logging.h"
|
| -#include "base/stl_util.h"
|
| -#include "net/quic/quic_connection_stats.h"
|
| -#include "net/quic/quic_utils_chromium.h"
|
| -
|
| -using std::max;
|
| -
|
| -namespace net {
|
| -
|
| -QuicUnackedPacketMap::QuicUnackedPacketMap()
|
| - : largest_sent_packet_(0),
|
| - largest_observed_(0),
|
| - least_unacked_(1),
|
| - bytes_in_flight_(0),
|
| - pending_crypto_packet_count_(0) {
|
| -}
|
| -
|
| -QuicUnackedPacketMap::~QuicUnackedPacketMap() {
|
| - QuicPacketSequenceNumber index = least_unacked_;
|
| - for (UnackedPacketMap::iterator it = unacked_packets_.begin();
|
| - it != unacked_packets_.end(); ++it, ++index) {
|
| - delete it->retransmittable_frames;
|
| - // Only delete all_transmissions once, for the newest packet.
|
| - if (it->all_transmissions != nullptr &&
|
| - index == *it->all_transmissions->rbegin()) {
|
| - delete it->all_transmissions;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void QuicUnackedPacketMap::AddSentPacket(
|
| - const SerializedPacket& packet,
|
| - QuicPacketSequenceNumber old_sequence_number,
|
| - TransmissionType transmission_type,
|
| - QuicTime sent_time,
|
| - QuicByteCount bytes_sent,
|
| - bool set_in_flight) {
|
| - QuicPacketSequenceNumber sequence_number = packet.sequence_number;
|
| - LOG_IF(DFATAL, largest_sent_packet_ > sequence_number);
|
| - DCHECK_GE(sequence_number, least_unacked_ + unacked_packets_.size());
|
| - while (least_unacked_ + unacked_packets_.size() < sequence_number) {
|
| - unacked_packets_.push_back(TransmissionInfo());
|
| - unacked_packets_.back().is_unackable = true;
|
| - }
|
| -
|
| - TransmissionInfo info(packet.retransmittable_frames,
|
| - packet.sequence_number_length,
|
| - transmission_type,
|
| - sent_time);
|
| - info.is_fec_packet = packet.is_fec_packet;
|
| -
|
| - if (old_sequence_number == 0) {
|
| - if (packet.retransmittable_frames != nullptr &&
|
| - packet.retransmittable_frames->HasCryptoHandshake() == IS_HANDSHAKE) {
|
| - ++pending_crypto_packet_count_;
|
| - }
|
| - } else {
|
| - TransferRetransmissionInfo(
|
| - old_sequence_number, sequence_number, transmission_type, &info);
|
| - }
|
| -
|
| - largest_sent_packet_ = sequence_number;
|
| - if (set_in_flight) {
|
| - bytes_in_flight_ += bytes_sent;
|
| - info.bytes_sent = bytes_sent;
|
| - info.in_flight = true;
|
| - }
|
| - unacked_packets_.push_back(info);
|
| -}
|
| -
|
| -void QuicUnackedPacketMap::RemoveObsoletePackets() {
|
| - while (!unacked_packets_.empty()) {
|
| - if (!IsPacketRemovable(least_unacked_, unacked_packets_.front())) {
|
| - break;
|
| - }
|
| - unacked_packets_.pop_front();
|
| - ++least_unacked_;
|
| - }
|
| -}
|
| -
|
| -void QuicUnackedPacketMap::TransferRetransmissionInfo(
|
| - QuicPacketSequenceNumber old_sequence_number,
|
| - QuicPacketSequenceNumber new_sequence_number,
|
| - TransmissionType transmission_type,
|
| - TransmissionInfo* info) {
|
| - DCHECK_GE(old_sequence_number, least_unacked_);
|
| - DCHECK_LT(old_sequence_number, least_unacked_ + unacked_packets_.size());
|
| - DCHECK_GE(new_sequence_number, least_unacked_ + unacked_packets_.size());
|
| - DCHECK_NE(NOT_RETRANSMISSION, transmission_type);
|
| -
|
| - // TODO(ianswett): Discard and lose the packet lazily instead of immediately.
|
| - TransmissionInfo* transmission_info =
|
| - &unacked_packets_.at(old_sequence_number - least_unacked_);
|
| - RetransmittableFrames* frames = transmission_info->retransmittable_frames;
|
| - transmission_info->retransmittable_frames = nullptr;
|
| - LOG_IF(DFATAL, frames == nullptr)
|
| - << "Attempt to retransmit packet with no "
|
| - << "retransmittable frames: " << old_sequence_number;
|
| -
|
| - // Only keep one transmission older than largest observed, because only the
|
| - // most recent is expected to possibly be a spurious retransmission.
|
| - while (transmission_info->all_transmissions != nullptr &&
|
| - transmission_info->all_transmissions->size() > 1 &&
|
| - *(++transmission_info->all_transmissions->begin()) <
|
| - largest_observed_) {
|
| - QuicPacketSequenceNumber old_transmission =
|
| - *transmission_info->all_transmissions->begin();
|
| - TransmissionInfo* old_info =
|
| - &unacked_packets_[old_transmission - least_unacked_];
|
| - // Don't remove old packets if they're still in flight.
|
| - if (old_info->in_flight) {
|
| - break;
|
| - }
|
| - old_info->all_transmissions->pop_front();
|
| - // This will cause the packet be removed in RemoveObsoletePackets.
|
| - old_info->all_transmissions = nullptr;
|
| - }
|
| - // 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 == nullptr) {
|
| - transmission_info->all_transmissions = new SequenceNumberList();
|
| - transmission_info->all_transmissions->push_back(old_sequence_number);
|
| - }
|
| - transmission_info->all_transmissions->push_back(new_sequence_number);
|
| - }
|
| - info->retransmittable_frames = frames;
|
| - info->all_transmissions = transmission_info->all_transmissions;
|
| - // Proactively remove obsolete packets so the least unacked can be raised.
|
| - RemoveObsoletePackets();
|
| -}
|
| -
|
| -void QuicUnackedPacketMap::ClearAllPreviousRetransmissions() {
|
| - while (!unacked_packets_.empty() && least_unacked_ < largest_observed_) {
|
| - // If this packet is in flight, or has retransmittable data, then there is
|
| - // no point in clearing out any further packets, because they would not
|
| - // affect the high water mark.
|
| - TransmissionInfo* info = &unacked_packets_.front();
|
| - if (info->in_flight || info->retransmittable_frames != nullptr) {
|
| - break;
|
| - }
|
| -
|
| - if (info->all_transmissions != nullptr) {
|
| - if (info->all_transmissions->size() < 2) {
|
| - LOG(DFATAL) << "all_transmissions must be nullptr or have multiple "
|
| - << "elements. size:" << info->all_transmissions->size();
|
| - delete info->all_transmissions;
|
| - } else {
|
| - info->all_transmissions->pop_front();
|
| - if (info->all_transmissions->size() == 1) {
|
| - // Set the newer transmission's 'all_transmissions' entry to nullptr.
|
| - QuicPacketSequenceNumber new_transmission =
|
| - info->all_transmissions->front();
|
| - TransmissionInfo* new_info =
|
| - &unacked_packets_.at(new_transmission - least_unacked_);
|
| - delete new_info->all_transmissions;
|
| - new_info->all_transmissions = nullptr;
|
| - }
|
| - }
|
| - }
|
| - unacked_packets_.pop_front();
|
| - ++least_unacked_;
|
| - }
|
| -}
|
| -
|
| -bool QuicUnackedPacketMap::HasRetransmittableFrames(
|
| - QuicPacketSequenceNumber sequence_number) const {
|
| - DCHECK_GE(sequence_number, least_unacked_);
|
| - DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
|
| - return unacked_packets_[sequence_number - least_unacked_]
|
| - .retransmittable_frames != nullptr;
|
| -}
|
| -
|
| -void QuicUnackedPacketMap::NackPacket(QuicPacketSequenceNumber sequence_number,
|
| - QuicPacketCount min_nacks) {
|
| - DCHECK_GE(sequence_number, least_unacked_);
|
| - DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
|
| - unacked_packets_[sequence_number - least_unacked_].nack_count =
|
| - max(min_nacks,
|
| - unacked_packets_[sequence_number - least_unacked_].nack_count);
|
| -}
|
| -
|
| -void QuicUnackedPacketMap::RemoveRetransmittability(
|
| - QuicPacketSequenceNumber sequence_number) {
|
| - DCHECK_GE(sequence_number, least_unacked_);
|
| - DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
|
| - TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_];
|
| - SequenceNumberList* all_transmissions = info->all_transmissions;
|
| - if (all_transmissions == nullptr) {
|
| - MaybeRemoveRetransmittableFrames(info);
|
| - return;
|
| - }
|
| - // TODO(ianswett): Consider adding a check to ensure there are retransmittable
|
| - // frames associated with this packet.
|
| - for (SequenceNumberList::const_iterator it = all_transmissions->begin();
|
| - it != all_transmissions->end(); ++it) {
|
| - TransmissionInfo* transmission_info =
|
| - &unacked_packets_[*it - least_unacked_];
|
| - MaybeRemoveRetransmittableFrames(transmission_info);
|
| - transmission_info->all_transmissions = nullptr;
|
| - }
|
| - delete all_transmissions;
|
| -}
|
| -
|
| -void QuicUnackedPacketMap::RemoveAckability(TransmissionInfo* info) {
|
| - DCHECK(info->retransmittable_frames == nullptr);
|
| - info->is_unackable = true;
|
| - SequenceNumberList* all_transmissions = info->all_transmissions;
|
| - if (all_transmissions == nullptr) {
|
| - 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 = nullptr;
|
| - transmission_info->is_unackable = true;
|
| - }
|
| - delete all_transmissions;
|
| -}
|
| -
|
| -void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames(
|
| - TransmissionInfo* transmission_info) {
|
| - if (transmission_info->retransmittable_frames != nullptr) {
|
| - if (transmission_info->retransmittable_frames->HasCryptoHandshake()
|
| - == IS_HANDSHAKE) {
|
| - --pending_crypto_packet_count_;
|
| - }
|
| - delete transmission_info->retransmittable_frames;
|
| - transmission_info->retransmittable_frames = nullptr;
|
| - }
|
| -}
|
| -
|
| -void QuicUnackedPacketMap::IncreaseLargestObserved(
|
| - QuicPacketSequenceNumber largest_observed) {
|
| - DCHECK_LE(largest_observed_, largest_observed);
|
| - largest_observed_ = largest_observed;
|
| -}
|
| -
|
| -bool QuicUnackedPacketMap::IsPacketUsefulForMeasuringRtt(
|
| - QuicPacketSequenceNumber sequence_number,
|
| - const TransmissionInfo& info) const {
|
| - // Packet can be used for RTT measurement if it may yet be acked as the
|
| - // largest observed packet by the receiver.
|
| - return !info.is_unackable && sequence_number > largest_observed_;
|
| -}
|
| -
|
| -bool QuicUnackedPacketMap::IsPacketUsefulForCongestionControl(
|
| - QuicPacketSequenceNumber sequence_number,
|
| - const TransmissionInfo& info) const {
|
| - // Packet contributes to congestion control if it is considered inflight.
|
| - return info.in_flight;
|
| -}
|
| -
|
| -bool QuicUnackedPacketMap::IsPacketUsefulForRetransmittableData(
|
| - QuicPacketSequenceNumber sequence_number,
|
| - const TransmissionInfo& info) const {
|
| - // Packet may have retransmittable frames, or the data may have been
|
| - // retransmitted with a new sequence number.
|
| - return info.retransmittable_frames != nullptr ||
|
| - info.all_transmissions != nullptr;
|
| -}
|
| -
|
| -bool QuicUnackedPacketMap::IsPacketUseless(
|
| - QuicPacketSequenceNumber sequence_number,
|
| - const TransmissionInfo& info) const {
|
| - return !IsPacketUsefulForMeasuringRtt(sequence_number, info) &&
|
| - !IsPacketUsefulForCongestionControl(sequence_number, info) &&
|
| - !IsPacketUsefulForRetransmittableData(sequence_number, info);
|
| -}
|
| -
|
| -bool QuicUnackedPacketMap::IsPacketRemovable(
|
| - QuicPacketSequenceNumber sequence_number,
|
| - const TransmissionInfo& info) const {
|
| - return (!IsPacketUsefulForMeasuringRtt(sequence_number, info) ||
|
| - unacked_packets_.size() > kMaxTcpCongestionWindow) &&
|
| - !IsPacketUsefulForCongestionControl(sequence_number, info) &&
|
| - !IsPacketUsefulForRetransmittableData(sequence_number, info);
|
| -}
|
| -
|
| -bool QuicUnackedPacketMap::IsUnacked(
|
| - QuicPacketSequenceNumber sequence_number) const {
|
| - if (sequence_number < least_unacked_ ||
|
| - sequence_number >= least_unacked_ + unacked_packets_.size()) {
|
| - return false;
|
| - }
|
| - return !IsPacketUseless(sequence_number,
|
| - unacked_packets_[sequence_number - least_unacked_]);
|
| -}
|
| -
|
| -void QuicUnackedPacketMap::RemoveFromInFlight(
|
| - QuicPacketSequenceNumber sequence_number) {
|
| - DCHECK_GE(sequence_number, least_unacked_);
|
| - DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
|
| - TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_];
|
| - if (info->in_flight) {
|
| - LOG_IF(DFATAL, bytes_in_flight_ < info->bytes_sent);
|
| - bytes_in_flight_ -= info->bytes_sent;
|
| - info->in_flight = false;
|
| - }
|
| -}
|
| -
|
| -bool QuicUnackedPacketMap::HasUnackedPackets() const {
|
| - return !unacked_packets_.empty();
|
| -}
|
| -
|
| -bool QuicUnackedPacketMap::HasInFlightPackets() const {
|
| - return bytes_in_flight_ > 0;
|
| -}
|
| -
|
| -const TransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo(
|
| - QuicPacketSequenceNumber sequence_number) const {
|
| - return unacked_packets_[sequence_number - least_unacked_];
|
| -}
|
| -
|
| -QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const {
|
| - UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin();
|
| - while (it != unacked_packets_.rend()) {
|
| - if (it->in_flight) {
|
| - LOG_IF(DFATAL, it->sent_time == QuicTime::Zero())
|
| - << "Sent time can never be zero for a packet in flight.";
|
| - return it->sent_time;
|
| - }
|
| - ++it;
|
| - }
|
| - LOG(DFATAL) << "GetLastPacketSentTime requires in flight packets.";
|
| - return QuicTime::Zero();
|
| -}
|
| -
|
| -QuicTime QuicUnackedPacketMap::GetFirstInFlightPacketSentTime() const {
|
| - UnackedPacketMap::const_iterator it = unacked_packets_.begin();
|
| - while (it != unacked_packets_.end() && !it->in_flight) {
|
| - ++it;
|
| - }
|
| - if (it == unacked_packets_.end()) {
|
| - LOG(DFATAL) << "GetFirstInFlightPacketSentTime requires in flight packets.";
|
| - return QuicTime::Zero();
|
| - }
|
| - return it->sent_time;
|
| -}
|
| -
|
| -size_t QuicUnackedPacketMap::GetNumUnackedPacketsDebugOnly() const {
|
| - size_t unacked_packet_count = 0;
|
| - QuicPacketSequenceNumber sequence_number = least_unacked_;
|
| - for (UnackedPacketMap::const_iterator it = unacked_packets_.begin();
|
| - it != unacked_packets_.end(); ++it, ++sequence_number) {
|
| - if (!IsPacketUseless(sequence_number, *it)) {
|
| - ++unacked_packet_count;
|
| - }
|
| - }
|
| - return unacked_packet_count;
|
| -}
|
| -
|
| -bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const {
|
| - size_t num_in_flight = 0;
|
| - for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin();
|
| - it != unacked_packets_.rend(); ++it) {
|
| - if (it->in_flight) {
|
| - ++num_in_flight;
|
| - }
|
| - if (num_in_flight > 1) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool QuicUnackedPacketMap::HasPendingCryptoPackets() const {
|
| - return pending_crypto_packet_count_ > 0;
|
| -}
|
| -
|
| -bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const {
|
| - for (UnackedPacketMap::const_reverse_iterator it =
|
| - unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) {
|
| - if (it->in_flight && it->retransmittable_frames) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -QuicPacketSequenceNumber
|
| -QuicUnackedPacketMap::GetLeastUnacked() const {
|
| - return least_unacked_;
|
| -}
|
| -
|
| -void QuicUnackedPacketMap::RestoreInFlight(
|
| - QuicPacketSequenceNumber sequence_number) {
|
| - DCHECK_GE(sequence_number, least_unacked_);
|
| - DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
|
| - TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_];
|
| - DCHECK(!info->in_flight);
|
| - DCHECK_NE(0u, info->bytes_sent);
|
| - DCHECK(info->sent_time.IsInitialized());
|
| -
|
| - bytes_in_flight_ += info->bytes_sent;
|
| - info->in_flight = true;
|
| -}
|
| -
|
| -} // namespace net
|
|
|