Index: net/quic/quic_connection.cc |
=================================================================== |
--- net/quic/quic_connection.cc (revision 171102) |
+++ net/quic/quic_connection.cc (working copy) |
@@ -24,14 +24,14 @@ |
namespace net { |
// An arbitrary number we'll probably want to tune. |
-const QuicPacketSequenceNumber kMaxAckedPackets = 5000u; |
+const QuicPacketSequenceNumber kMaxUnackedPackets = 5000u; |
// The amount of time we wait before resending a packet. |
const int64 kDefaultResendTimeMs = 500; |
bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { |
QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; |
- return delta <= kMaxAckedPackets; |
+ return delta <= kMaxUnackedPackets; |
} |
QuicConnection::QuicConnection(QuicGuid guid, |
@@ -105,7 +105,8 @@ |
ReceivedPacketInfo info = outgoing_ack_.received_info; |
// If this packet has already been seen, or that the sender |
// has told us will not be resent, then stop processing the packet. |
- if (info.ContainsAck(header.packet_sequence_number)) { |
+ if (header.packet_sequence_number <= info.largest_received && |
+ info.missing_packets.count(header.packet_sequence_number) != 1) { |
return false; |
} |
@@ -167,10 +168,12 @@ |
return false; |
} |
- // We can't have too many acked packets, or our ack frames go over |
- // kMaxPacketSize. |
- DCHECK_LT(incoming_ack.received_info.received_packet_times.size(), |
- kMaxAckedPackets); |
+ // We can't have too many missing or retransmitting packets, or our ack |
+ // frames go over kMaxPacketSize. |
+ DCHECK_LT(incoming_ack.received_info.missing_packets.size(), |
+ kMaxUnackedPackets); |
+ DCHECK_LT(incoming_ack.sent_info.non_retransmiting.size(), |
+ kMaxUnackedPackets); |
if (incoming_ack.sent_info.least_unacked != 0 && |
incoming_ack.sent_info.least_unacked < least_packet_awaiting_ack_) { |
@@ -196,7 +199,9 @@ |
// incoming_ack shows they've been seen by the peer. |
UnackedPacketMap::iterator it = unacked_packets_.begin(); |
while (it != unacked_packets_.end()) { |
- if (incoming_ack.received_info.ContainsAck(it->first)) { |
+ if ((it->first < incoming_ack.received_info.largest_received && |
+ !ContainsKey(incoming_ack.received_info.missing_packets, it->first)) || |
+ it->first == incoming_ack.received_info.largest_received) { |
// Packet was acked, so remove it from our unacked packet list. |
DVLOG(1) << "Got an ack for " << it->first; |
// TODO(rch): This is inefficient and should be sped up. |
@@ -231,9 +236,17 @@ |
// If we've gotten an ack for the lowest packet we were waiting on, |
// update that and the list of packets we advertise we will not resend. |
if (lowest_unacked > outgoing_ack_.sent_info.least_unacked) { |
+ SequenceSet* non_retrans = &outgoing_ack_.sent_info.non_retransmiting; |
+ // We don't need to advertise not-resending packets between the old |
+ // and new values. |
+ for (QuicPacketSequenceNumber i = outgoing_ack_.sent_info.least_unacked; |
+ i < lowest_unacked; ++i) { |
+ non_retrans->erase(i); |
+ } |
// If all packets we sent have been acked, use the special value of 0 |
if (lowest_unacked > packet_creator_.sequence_number()) { |
lowest_unacked = 0; |
+ DCHECK_EQ(0u, non_retrans->size()); |
} |
outgoing_ack_.sent_info.least_unacked = lowest_unacked; |
} |
@@ -241,11 +254,22 @@ |
void QuicConnection::UpdatePacketInformationSentByPeer( |
const QuicAckFrame& incoming_ack) { |
- // Make sure we also don't ack any packets lower than the peer's |
+ // Iteratate through the packets which will the peer will not resend and |
+ // remove them from our missing list. |
+ for (SequenceSet::const_iterator it = |
+ incoming_ack.sent_info.non_retransmiting.begin(); |
+ it != incoming_ack.sent_info.non_retransmiting.end(); ++it) { |
+ DVLOG(1) << "no longer expecting " << *it; |
+ outgoing_ack_.received_info.missing_packets.erase(*it); |
+ } |
+ |
+ // Make sure we also don't expect any packets lower than the peer's |
// last-packet-awaiting-ack. |
if (incoming_ack.sent_info.least_unacked > least_packet_awaiting_ack_) { |
- outgoing_ack_.received_info.ClearAcksBefore( |
- incoming_ack.sent_info.least_unacked); |
+ for (QuicPacketSequenceNumber i = least_packet_awaiting_ack_; |
+ i < incoming_ack.sent_info.least_unacked; ++i) { |
+ outgoing_ack_.received_info.missing_packets.erase(i); |
+ } |
least_packet_awaiting_ack_ = incoming_ack.sent_info.least_unacked; |
} |
@@ -370,7 +394,23 @@ |
void QuicConnection::AckPacket(const QuicPacketHeader& header) { |
QuicPacketSequenceNumber sequence_number = header.packet_sequence_number; |
- outgoing_ack_.received_info.RecordAck(sequence_number, clock_->Now()); |
+ if (sequence_number > outgoing_ack_.received_info.largest_received) { |
+ // We've got a new high sequence number. Note any new intermediate missing |
+ // packets, and update the last_ack data. |
+ for (QuicPacketSequenceNumber i = |
+ outgoing_ack_.received_info.largest_received + 1; |
+ i < sequence_number; ++i) { |
+ DVLOG(1) << "missing " << i; |
+ outgoing_ack_.received_info.missing_packets.insert(i); |
+ } |
+ outgoing_ack_.received_info.largest_received = sequence_number; |
+ outgoing_ack_.received_info.time_received = clock_->Now(); |
+ } else { |
+ // We've gotten one of the out of order packets - remove it from our |
+ // "missing packets" list. |
+ DVLOG(1) << "Removing " << sequence_number << " from missing list"; |
+ outgoing_ack_.received_info.missing_packets.erase(sequence_number); |
+ } |
// TODO(alyssar) delay sending until we have data, or enough time has elapsed. |
if (frames_.size() > 0) { |
SendAck(); |
@@ -431,6 +471,11 @@ |
sequence_number < outgoing_ack_.sent_info.least_unacked) { |
outgoing_ack_.sent_info.least_unacked = sequence_number; |
} |
+ } else { |
+ if (outgoing_ack_.sent_info.least_unacked != 0 && |
+ sequence_number > outgoing_ack_.sent_info.least_unacked) { |
+ outgoing_ack_.sent_info.non_retransmiting.insert(sequence_number); |
+ } |
} |
scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket(*packet)); |