diff options
author | Andras Becsi <andras.becsi@digia.com> | 2013-12-11 21:33:03 +0100 |
---|---|---|
committer | Andras Becsi <andras.becsi@digia.com> | 2013-12-13 12:34:07 +0100 |
commit | f2a33ff9cbc6d19943f1c7fbddd1f23d23975577 (patch) | |
tree | 0586a32aa390ade8557dfd6b4897f43a07449578 /chromium/net/quic/quic_sent_packet_manager.cc | |
parent | 5362912cdb5eea702b68ebe23702468d17c3017a (diff) | |
download | qtwebengine-chromium-f2a33ff9cbc6d19943f1c7fbddd1f23d23975577.tar.gz |
Update Chromium to branch 1650 (31.0.1650.63)
Change-Id: I57d8c832eaec1eb2364e0a8e7352a6dd354db99f
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
Diffstat (limited to 'chromium/net/quic/quic_sent_packet_manager.cc')
-rw-r--r-- | chromium/net/quic/quic_sent_packet_manager.cc | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/chromium/net/quic/quic_sent_packet_manager.cc b/chromium/net/quic/quic_sent_packet_manager.cc new file mode 100644 index 00000000000..a8960f07aa0 --- /dev/null +++ b/chromium/net/quic/quic_sent_packet_manager.cc @@ -0,0 +1,221 @@ +// Copyright 2013 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_sent_packet_manager.h" + +#include "base/logging.h" +#include "base/stl_util.h" + +using std::make_pair; + +namespace net { + +#define ENDPOINT (is_server_ ? "Server: " : " Client: ") + +QuicSentPacketManager::HelperInterface::~HelperInterface() { +} + +QuicSentPacketManager::QuicSentPacketManager(bool is_server, + HelperInterface* helper) + : is_server_(is_server), + helper_(helper) { +} + +QuicSentPacketManager::~QuicSentPacketManager() { + STLDeleteValues(&unacked_packets_); +} + +void QuicSentPacketManager::OnSerializedPacket( + const SerializedPacket& serialized_packet) { + if (serialized_packet.packet->is_fec_packet()) { + unacked_fec_packets_.insert(make_pair( + serialized_packet.sequence_number, + serialized_packet.retransmittable_frames)); + return; + } + + if (serialized_packet.retransmittable_frames == NULL) { + // Don't track ack/congestion feedback packets. + return; + } + + DCHECK(unacked_packets_.empty() || + unacked_packets_.rbegin()->first < + serialized_packet.sequence_number); + unacked_packets_[serialized_packet.sequence_number] = + serialized_packet.retransmittable_frames; + retransmission_map_[serialized_packet.sequence_number] = + RetransmissionInfo(serialized_packet.sequence_number, + serialized_packet.sequence_number_length); +} + +void QuicSentPacketManager::OnRetransmittedPacket( + QuicPacketSequenceNumber old_sequence_number, + QuicPacketSequenceNumber new_sequence_number) { + DCHECK(ContainsKey(unacked_packets_, old_sequence_number)); + DCHECK(ContainsKey(retransmission_map_, old_sequence_number)); + DCHECK(unacked_packets_.empty() || + unacked_packets_.rbegin()->first < new_sequence_number); + + RetransmissionInfo retransmission_info( + new_sequence_number, GetSequenceNumberLength(old_sequence_number)); + retransmission_info.number_retransmissions = + retransmission_map_[old_sequence_number].number_retransmissions + 1; + retransmission_map_.erase(old_sequence_number); + retransmission_map_[new_sequence_number] = retransmission_info; + + RetransmittableFrames* frames = unacked_packets_[old_sequence_number]; + DCHECK(frames); + unacked_packets_.erase(old_sequence_number); + unacked_packets_[new_sequence_number] = frames; +} + +void QuicSentPacketManager::HandleAckForSentPackets( + const QuicAckFrame& incoming_ack, + SequenceNumberSet* acked_packets) { + // Go through the packets we have not received an ack for and see if this + // incoming_ack shows they've been seen by the peer. + UnackedPacketMap::iterator it = unacked_packets_.begin(); + while (it != unacked_packets_.end()) { + QuicPacketSequenceNumber sequence_number = it->first; + if (sequence_number > helper_->GetPeerLargestObservedPacket()) { + // These are very new sequence_numbers. + break; + } + RetransmittableFrames* unacked = it->second; + if (!IsAwaitingPacket(incoming_ack.received_info, sequence_number)) { + // Packet was acked, so remove it from our unacked packet list. + DVLOG(1) << ENDPOINT <<"Got an ack for packet " << sequence_number; + acked_packets->insert(sequence_number); + delete unacked; + unacked_packets_.erase(it++); + retransmission_map_.erase(sequence_number); + } else { + // This is a packet which we planned on retransmitting and has not been + // seen at the time of this ack being sent out. See if it's our new + // lowest unacked packet. + DVLOG(1) << ENDPOINT << "still missing packet " << sequence_number; + ++it; + // The peer got packets after this sequence number. This is an explicit + // nack. + RetransmissionMap::iterator retransmission_it = + retransmission_map_.find(sequence_number); + if (retransmission_it == retransmission_map_.end()) { + continue; + } + size_t nack_count = ++(retransmission_it->second.number_nacks); + helper_->OnPacketNacked(sequence_number, nack_count); + } + } +} + +void QuicSentPacketManager::HandleAckForSentFecPackets( + const QuicAckFrame& incoming_ack, + SequenceNumberSet* acked_packets) { + UnackedPacketMap::iterator it = unacked_fec_packets_.begin(); + while (it != unacked_fec_packets_.end()) { + QuicPacketSequenceNumber sequence_number = it->first; + if (sequence_number > helper_->GetPeerLargestObservedPacket()) { + break; + } + if (!IsAwaitingPacket(incoming_ack.received_info, sequence_number)) { + DVLOG(1) << ENDPOINT << "Got an ack for fec packet: " << sequence_number; + acked_packets->insert(sequence_number); + unacked_fec_packets_.erase(it++); + } else { + DVLOG(1) << ENDPOINT << "Still missing ack for fec packet: " + << sequence_number; + ++it; + } + } +} + +void QuicSentPacketManager::DiscardPacket( + QuicPacketSequenceNumber sequence_number) { + UnackedPacketMap::iterator unacked_it = + unacked_packets_.find(sequence_number); + if (unacked_it == unacked_packets_.end()) { + // Packet was not meant to be retransmitted. + DCHECK(!ContainsKey(retransmission_map_, sequence_number)); + return; + } + + // Delete the unacked packet. + delete unacked_it->second; + unacked_packets_.erase(unacked_it); + retransmission_map_.erase(sequence_number); +} + +bool QuicSentPacketManager::IsRetransmission( + QuicPacketSequenceNumber sequence_number) const { + RetransmissionMap::const_iterator it = + retransmission_map_.find(sequence_number); + return it != retransmission_map_.end() && + it->second.number_retransmissions > 0; +} + +size_t QuicSentPacketManager::GetRetransmissionCount( + QuicPacketSequenceNumber sequence_number) const { + DCHECK(ContainsKey(retransmission_map_, sequence_number)); + RetransmissionMap::const_iterator it = + retransmission_map_.find(sequence_number); + return it->second.number_retransmissions; +} + +bool QuicSentPacketManager::IsUnacked( + QuicPacketSequenceNumber sequence_number) const { + return ContainsKey(unacked_packets_, sequence_number); +} + +bool QuicSentPacketManager::IsFecUnacked( + QuicPacketSequenceNumber sequence_number) const { + return ContainsKey(unacked_fec_packets_, sequence_number); +} + +const RetransmittableFrames& QuicSentPacketManager::GetRetransmittableFrames( + QuicPacketSequenceNumber sequence_number) const { + DCHECK(ContainsKey(unacked_packets_, sequence_number)); + DCHECK(ContainsKey(retransmission_map_, sequence_number)); + + return *unacked_packets_.find(sequence_number)->second; +} + +QuicSequenceNumberLength QuicSentPacketManager::GetSequenceNumberLength( + QuicPacketSequenceNumber sequence_number) const { + DCHECK(ContainsKey(unacked_packets_, sequence_number)); + DCHECK(ContainsKey(retransmission_map_, sequence_number)); + + return retransmission_map_.find( + sequence_number)->second.sequence_number_length; +} + +bool QuicSentPacketManager::HasUnackedPackets() const { + return !unacked_packets_.empty(); +} + +size_t QuicSentPacketManager::GetNumUnackedPackets() const { + return unacked_packets_.size(); +} + +QuicPacketSequenceNumber +QuicSentPacketManager::GetLeastUnackedSentPacket() const { + if (unacked_packets_.empty()) { + // If there are no unacked packets, set the least unacked packet to + // the sequence number of the next packet sent. + return helper_->GetNextPacketSequenceNumber(); + } + + return unacked_packets_.begin()->first; +} + +SequenceNumberSet QuicSentPacketManager::GetUnackedPackets() const { + SequenceNumberSet unacked_packets; + for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); + it != unacked_packets_.end(); ++it) { + unacked_packets.insert(it->first); + } + return unacked_packets; +} + +} // namespace net |