Commit ef442aa7 authored by rch@chromium.org's avatar rch@chromium.org

Adding transmission times for every QUIC packet received in the AckFrame.

Making the scheduler a strict mock for quic connection test.

Merge internal change: 39116450
Merge internal change: 38802607


Review URL: https://chromiumcodereview.appspot.com/11416155

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171096 0039d316-1c4b-4281-b951-d872f2087c98
parent e490611e
...@@ -97,8 +97,7 @@ void QuicSendScheduler::OnIncomingAckFrame(const QuicAckFrame& ack_frame) { ...@@ -97,8 +97,7 @@ void QuicSendScheduler::OnIncomingAckFrame(const QuicAckFrame& ack_frame) {
while (it != it_upper) { while (it != it_upper) {
QuicPacketSequenceNumber sequence_number = it->first; QuicPacketSequenceNumber sequence_number = it->first;
if (ack_frame.received_info.missing_packets.find(sequence_number) == if (ack_frame.received_info.ContainsAck(sequence_number)) {
ack_frame.received_info.missing_packets.end()) {
// Not missing, hence implicitly acked. // Not missing, hence implicitly acked.
scoped_ptr<PendingPacket> pending_packet_cleaner(it->second); scoped_ptr<PendingPacket> pending_packet_cleaner(it->second);
acked_packets[sequence_number] = pending_packet_cleaner->BytesSent(); acked_packets[sequence_number] = pending_packet_cleaner->BytesSent();
......
...@@ -59,7 +59,7 @@ TEST_F(QuicSendSchedulerTest, FixedRatePacing) { ...@@ -59,7 +59,7 @@ TEST_F(QuicSendSchedulerTest, FixedRatePacing) {
clock_.AdvanceTime(advance_time); clock_.AdvanceTime(advance_time);
acc_advance_time = acc_advance_time.Add(advance_time); acc_advance_time = acc_advance_time.Add(advance_time);
// Ack the packet we sent. // Ack the packet we sent.
ack.received_info.largest_received = i; ack.received_info.RecordAck(i, acc_advance_time);
sender_->OnIncomingAckFrame(ack); sender_->OnIncomingAckFrame(ack);
} }
EXPECT_EQ(QuicTime::FromMilliseconds(1200), acc_advance_time); EXPECT_EQ(QuicTime::FromMilliseconds(1200), acc_advance_time);
...@@ -78,8 +78,10 @@ TEST_F(QuicSendSchedulerTest, AvailableCongestionWindow) { ...@@ -78,8 +78,10 @@ TEST_F(QuicSendSchedulerTest, AvailableCongestionWindow) {
sender_->SentPacket(i, 100, false); sender_->SentPacket(i, 100, false);
EXPECT_EQ(kMaxPacketSize - (i * 100), sender_->AvailableCongestionWindow()); EXPECT_EQ(kMaxPacketSize - (i * 100), sender_->AvailableCongestionWindow());
} }
// Ack the packet we sent. // Ack the packets we sent.
ack.received_info.largest_received = 12; for (int i = 1; i <= 12; i++) {
ack.received_info.RecordAck(i, QuicTime::FromMilliseconds(100));
}
sender_->OnIncomingAckFrame(ack); sender_->OnIncomingAckFrame(ack);
EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow()); EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow());
} }
...@@ -97,7 +99,7 @@ TEST_F(QuicSendSchedulerTest, FixedRateBandwidth) { ...@@ -97,7 +99,7 @@ TEST_F(QuicSendSchedulerTest, FixedRateBandwidth) {
EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow()); EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow());
sender_->SentPacket(i, 1000, false); sender_->SentPacket(i, 1000, false);
// Ack the packet we sent. // Ack the packet we sent.
ack.received_info.largest_received = i; ack.received_info.RecordAck(i, clock_.Now());
sender_->OnIncomingAckFrame(ack); sender_->OnIncomingAckFrame(ack);
} }
EXPECT_EQ(100000, sender_->BandwidthEstimate()); EXPECT_EQ(100000, sender_->BandwidthEstimate());
...@@ -117,7 +119,7 @@ TEST_F(QuicSendSchedulerTest, BandwidthWith3SecondGap) { ...@@ -117,7 +119,7 @@ TEST_F(QuicSendSchedulerTest, BandwidthWith3SecondGap) {
EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow()); EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow());
sender_->SentPacket(i, 1000, false); sender_->SentPacket(i, 1000, false);
// Ack the packet we sent. // Ack the packet we sent.
ack.received_info.largest_received = i; ack.received_info.RecordAck(i, clock_.Now());
sender_->OnIncomingAckFrame(ack); sender_->OnIncomingAckFrame(ack);
} }
EXPECT_EQ(100000, sender_->BandwidthEstimate()); EXPECT_EQ(100000, sender_->BandwidthEstimate());
...@@ -135,7 +137,7 @@ TEST_F(QuicSendSchedulerTest, BandwidthWith3SecondGap) { ...@@ -135,7 +137,7 @@ TEST_F(QuicSendSchedulerTest, BandwidthWith3SecondGap) {
sender_->SentPacket(i + 100, 1000, false); sender_->SentPacket(i + 100, 1000, false);
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10)); clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
// Ack the packet we sent. // Ack the packet we sent.
ack.received_info.largest_received = i + 100; ack.received_info.RecordAck(i + 100, clock_.Now());
sender_->OnIncomingAckFrame(ack); sender_->OnIncomingAckFrame(ack);
} }
EXPECT_EQ(100000, sender_->BandwidthEstimate()); EXPECT_EQ(100000, sender_->BandwidthEstimate());
...@@ -162,9 +164,9 @@ TEST_F(QuicSendSchedulerTest, Pacing) { ...@@ -162,9 +164,9 @@ TEST_F(QuicSendSchedulerTest, Pacing) {
clock_.AdvanceTime(advance_time); clock_.AdvanceTime(advance_time);
acc_advance_time = acc_advance_time.Add(advance_time); acc_advance_time = acc_advance_time.Add(advance_time);
// Ack the packets we sent. // Ack the packets we sent.
ack.received_info.largest_received = i - 2; ack.received_info.RecordAck(i - 2, clock_.Now());
sender_->OnIncomingAckFrame(ack); sender_->OnIncomingAckFrame(ack);
ack.received_info.largest_received = i - 1; ack.received_info.RecordAck(i - 1, clock_.Now());
sender_->OnIncomingAckFrame(ack); sender_->OnIncomingAckFrame(ack);
} }
EXPECT_EQ(QuicTime::FromMilliseconds(120), acc_advance_time); EXPECT_EQ(QuicTime::FromMilliseconds(120), acc_advance_time);
......
...@@ -24,14 +24,14 @@ using std::set; ...@@ -24,14 +24,14 @@ using std::set;
namespace net { namespace net {
// An arbitrary number we'll probably want to tune. // An arbitrary number we'll probably want to tune.
const QuicPacketSequenceNumber kMaxUnackedPackets = 5000u; const QuicPacketSequenceNumber kMaxAckedPackets = 5000u;
// The amount of time we wait before resending a packet. // The amount of time we wait before resending a packet.
const int64 kDefaultResendTimeMs = 500; const int64 kDefaultResendTimeMs = 500;
bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) {
QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a;
return delta <= kMaxUnackedPackets; return delta <= kMaxAckedPackets;
} }
QuicConnection::QuicConnection(QuicGuid guid, QuicConnection::QuicConnection(QuicGuid guid,
...@@ -105,8 +105,7 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { ...@@ -105,8 +105,7 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
ReceivedPacketInfo info = outgoing_ack_.received_info; ReceivedPacketInfo info = outgoing_ack_.received_info;
// If this packet has already been seen, or that the sender // If this packet has already been seen, or that the sender
// has told us will not be resent, then stop processing the packet. // has told us will not be resent, then stop processing the packet.
if (header.packet_sequence_number <= info.largest_received && if (info.ContainsAck(header.packet_sequence_number)) {
info.missing_packets.count(header.packet_sequence_number) != 1) {
return false; return false;
} }
...@@ -168,12 +167,10 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) { ...@@ -168,12 +167,10 @@ bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
return false; return false;
} }
// We can't have too many missing or retransmitting packets, or our ack // We can't have too many acked packets, or our ack frames go over
// frames go over kMaxPacketSize. // kMaxPacketSize.
DCHECK_LT(incoming_ack.received_info.missing_packets.size(), DCHECK_LT(incoming_ack.received_info.received_packet_times.size(),
kMaxUnackedPackets); kMaxAckedPackets);
DCHECK_LT(incoming_ack.sent_info.non_retransmiting.size(),
kMaxUnackedPackets);
if (incoming_ack.sent_info.least_unacked != 0 && if (incoming_ack.sent_info.least_unacked != 0 &&
incoming_ack.sent_info.least_unacked < least_packet_awaiting_ack_) { incoming_ack.sent_info.least_unacked < least_packet_awaiting_ack_) {
...@@ -199,9 +196,7 @@ void QuicConnection::UpdatePacketInformationReceivedByPeer( ...@@ -199,9 +196,7 @@ void QuicConnection::UpdatePacketInformationReceivedByPeer(
// incoming_ack shows they've been seen by the peer. // incoming_ack shows they've been seen by the peer.
UnackedPacketMap::iterator it = unacked_packets_.begin(); UnackedPacketMap::iterator it = unacked_packets_.begin();
while (it != unacked_packets_.end()) { while (it != unacked_packets_.end()) {
if ((it->first < incoming_ack.received_info.largest_received && if (incoming_ack.received_info.ContainsAck(it->first)) {
!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. // Packet was acked, so remove it from our unacked packet list.
DVLOG(1) << "Got an ack for " << it->first; DVLOG(1) << "Got an ack for " << it->first;
// TODO(rch): This is inefficient and should be sped up. // TODO(rch): This is inefficient and should be sped up.
...@@ -236,17 +231,9 @@ void QuicConnection::UpdatePacketInformationReceivedByPeer( ...@@ -236,17 +231,9 @@ void QuicConnection::UpdatePacketInformationReceivedByPeer(
// If we've gotten an ack for the lowest packet we were waiting on, // 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. // update that and the list of packets we advertise we will not resend.
if (lowest_unacked > outgoing_ack_.sent_info.least_unacked) { 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 all packets we sent have been acked, use the special value of 0
if (lowest_unacked > packet_creator_.sequence_number()) { if (lowest_unacked > packet_creator_.sequence_number()) {
lowest_unacked = 0; lowest_unacked = 0;
DCHECK_EQ(0u, non_retrans->size());
} }
outgoing_ack_.sent_info.least_unacked = lowest_unacked; outgoing_ack_.sent_info.least_unacked = lowest_unacked;
} }
...@@ -254,22 +241,11 @@ void QuicConnection::UpdatePacketInformationReceivedByPeer( ...@@ -254,22 +241,11 @@ void QuicConnection::UpdatePacketInformationReceivedByPeer(
void QuicConnection::UpdatePacketInformationSentByPeer( void QuicConnection::UpdatePacketInformationSentByPeer(
const QuicAckFrame& incoming_ack) { const QuicAckFrame& incoming_ack) {
// Iteratate through the packets which will the peer will not resend and // Make sure we also don't ack any packets lower than the peer's
// 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. // last-packet-awaiting-ack.
if (incoming_ack.sent_info.least_unacked > least_packet_awaiting_ack_) { if (incoming_ack.sent_info.least_unacked > least_packet_awaiting_ack_) {
for (QuicPacketSequenceNumber i = least_packet_awaiting_ack_; outgoing_ack_.received_info.ClearAcksBefore(
i < incoming_ack.sent_info.least_unacked; ++i) { incoming_ack.sent_info.least_unacked);
outgoing_ack_.received_info.missing_packets.erase(i);
}
least_packet_awaiting_ack_ = incoming_ack.sent_info.least_unacked; least_packet_awaiting_ack_ = incoming_ack.sent_info.least_unacked;
} }
...@@ -394,23 +370,7 @@ bool QuicConnection::OnCanWrite() { ...@@ -394,23 +370,7 @@ bool QuicConnection::OnCanWrite() {
void QuicConnection::AckPacket(const QuicPacketHeader& header) { void QuicConnection::AckPacket(const QuicPacketHeader& header) {
QuicPacketSequenceNumber sequence_number = header.packet_sequence_number; QuicPacketSequenceNumber sequence_number = header.packet_sequence_number;
if (sequence_number > outgoing_ack_.received_info.largest_received) { outgoing_ack_.received_info.RecordAck(sequence_number, clock_->Now());
// 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. // TODO(alyssar) delay sending until we have data, or enough time has elapsed.
if (frames_.size() > 0) { if (frames_.size() > 0) {
SendAck(); SendAck();
...@@ -471,11 +431,6 @@ bool QuicConnection::SendPacket(QuicPacketSequenceNumber sequence_number, ...@@ -471,11 +431,6 @@ bool QuicConnection::SendPacket(QuicPacketSequenceNumber sequence_number,
sequence_number < outgoing_ack_.sent_info.least_unacked) { sequence_number < outgoing_ack_.sent_info.least_unacked) {
outgoing_ack_.sent_info.least_unacked = sequence_number; 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)); scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket(*packet));
......
...@@ -132,9 +132,9 @@ class QuicConnectionHelperTest : public ::testing::Test { ...@@ -132,9 +132,9 @@ class QuicConnectionHelperTest : public ::testing::Test {
InitializeHeader(sequence_number); InitializeHeader(sequence_number);
QuicAckFrame ack(0, QuicTime(), 0); QuicAckFrame ack(0, QuicTime(), 0);
ack.congestion_info.type = kFixRate; ack.congestion_info.type = kFixRate;
ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 100000; ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 100000;
return ConstructPacket(header_, QuicFrame(&ack)); return ConstructPacket(header_, QuicFrame(&ack));
} }
......
This diff is collapsed.
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "net/quic/quic_utils.h" #include "net/quic/quic_utils.h"
using base::StringPiece; using base::StringPiece;
using std::map;
namespace net { namespace net {
...@@ -353,31 +354,46 @@ bool QuicFramer::ProcessPDUFrame() { ...@@ -353,31 +354,46 @@ bool QuicFramer::ProcessPDUFrame() {
} }
bool QuicFramer::ProcessAckFrame(QuicAckFrame* frame) { bool QuicFramer::ProcessAckFrame(QuicAckFrame* frame) {
if (!reader_->ReadUInt48(&frame->received_info.largest_received)) { uint8 num_acked_packets;
set_detailed_error("Unable to read largest received."); if (!reader_->ReadBytes(&num_acked_packets, 1)) {
set_detailed_error("Unable to read num acked packets.");
return false; return false;
} }
uint64 time_received;
if (!reader_->ReadUInt64(&time_received)) { uint64 smallest_received;
set_detailed_error("Unable to read time received."); if (!reader_->ReadUInt48(&smallest_received)) {
set_detailed_error("Unable to read smallest received.");
return false; return false;
} }
frame->received_info.time_received =
QuicTime::FromMicroseconds(time_received);
uint8 num_unacked_packets; if (num_acked_packets == 0u) {
if (!reader_->ReadBytes(&num_unacked_packets, 1)) { // Ensures largest_received is set when no actual acks are transmitted.
set_detailed_error("Unable to read num unacked packets."); frame->received_info.largest_received = smallest_received;
} else {
uint64 time_received_us;
if (!reader_->ReadUInt64(&time_received_us)) {
set_detailed_error("Unable to read time received.");
return false; return false;
} }
for (int i = 0; i < num_unacked_packets; ++i) { frame->received_info.RecordAck(
QuicPacketSequenceNumber sequence_number; smallest_received, QuicTime::FromMicroseconds(time_received_us));
if (!reader_->ReadUInt48(&sequence_number)) {
set_detailed_error("Unable to read sequence number in unacked packets."); for (int i = 0; i < num_acked_packets - 1; ++i) {
uint8 sequence_delta;
if (!reader_->ReadBytes(&sequence_delta, 1)) {
set_detailed_error("Unable to read sequence delta in acked packets.");
return false;
}
int32 time_delta_us;
if (!reader_->ReadBytes(&time_delta_us, sizeof(time_delta_us))) {
set_detailed_error("Unable to read time delta in acked packets.");
return false; return false;
} }
frame->received_info.missing_packets.insert(sequence_number); frame->received_info.RecordAck(
smallest_received + sequence_delta,
QuicTime::FromMicroseconds(time_received_us + time_delta_us));
}
} }
if (!reader_->ReadUInt48(&frame->sent_info.least_unacked)) { if (!reader_->ReadUInt48(&frame->sent_info.least_unacked)) {
...@@ -385,21 +401,6 @@ bool QuicFramer::ProcessAckFrame(QuicAckFrame* frame) { ...@@ -385,21 +401,6 @@ bool QuicFramer::ProcessAckFrame(QuicAckFrame* frame) {
return false; return false;
} }
uint8 num_non_retransmiting_packets;
if (!reader_->ReadBytes(&num_non_retransmiting_packets, 1)) {
set_detailed_error("Unable to read num non-retransmitting.");
return false;
}
for (uint8 i = 0; i < num_non_retransmiting_packets; ++i) {
QuicPacketSequenceNumber sequence_number;
if (!reader_->ReadUInt48(&sequence_number)) {
set_detailed_error(
"Unable to read sequence number in non-retransmitting.");
return false;
}
frame->sent_info.non_retransmiting.insert(sequence_number);
}
uint8 congestion_info_type; uint8 congestion_info_type;
if (!reader_->ReadBytes(&congestion_info_type, 1)) { if (!reader_->ReadBytes(&congestion_info_type, 1)) {
set_detailed_error("Unable to read congestion info type."); set_detailed_error("Unable to read congestion info type.");
...@@ -582,13 +583,13 @@ size_t QuicFramer::ComputeFramePayloadLength(const QuicFrame& frame) { ...@@ -582,13 +583,13 @@ size_t QuicFramer::ComputeFramePayloadLength(const QuicFrame& frame) {
break; // Need to support this eventually :> break; // Need to support this eventually :>
case ACK_FRAME: { case ACK_FRAME: {
const QuicAckFrame& ack = *frame.ack_frame; const QuicAckFrame& ack = *frame.ack_frame;
len += 1; // num acked packets
len += 6; // largest received packet sequence number len += 6; // largest received packet sequence number
len += 8; // time delta if (ack.received_info.received_packet_times.size() > 0) {
len += 1; // num missing packets len += 8; // time
len += 6 * ack.received_info.missing_packets.size(); len += 5 * (ack.received_info.received_packet_times.size() - 1);
}
len += 6; // least packet sequence number awaiting an ack len += 6; // least packet sequence number awaiting an ack
len += 1; // num non retransmitting packets
len += 6 * ack.sent_info.non_retransmiting.size();
len += 1; // congestion control type len += 1; // congestion control type
switch (ack.congestion_info.type) { switch (ack.congestion_info.type) {
case kNone: case kNone:
...@@ -656,44 +657,47 @@ bool QuicFramer::AppendStreamFramePayload( ...@@ -656,44 +657,47 @@ bool QuicFramer::AppendStreamFramePayload(
bool QuicFramer::AppendAckFramePayload( bool QuicFramer::AppendAckFramePayload(
const QuicAckFrame& frame, const QuicAckFrame& frame,
QuicDataWriter* writer) { QuicDataWriter* writer) {
if (!writer->WriteUInt48(frame.received_info.largest_received)) { uint8 num_acked_packets = frame.received_info.received_packet_times.size();
if (!writer->WriteBytes(&num_acked_packets, 1)) {
return false; return false;
} }
if (num_acked_packets == 0) {
if (!writer->WriteUInt64( // Special case when no packets are acked, just transmit the largest.
frame.received_info.time_received.ToMicroseconds())) { if (!writer->WriteUInt48(frame.received_info.largest_received)) {
return false; return false;
} }
} else {
map<QuicPacketSequenceNumber, QuicTime>::const_iterator it =
frame.received_info.received_packet_times.begin();
size_t num_unacked_packets = frame.received_info.missing_packets.size(); QuicPacketSequenceNumber lowest_sequence = it->first;
if (!writer->WriteBytes(&num_unacked_packets, 1)) { if (!writer->WriteUInt48(lowest_sequence)) {
return false; return false;
} }
SequenceSet::const_iterator it = frame.received_info.missing_packets.begin(); QuicTime lowest_time = it->second;
for (; it != frame.received_info.missing_packets.end(); ++it) { // TODO(ianswett): Use time deltas from the connection's first received
if (!writer->WriteUInt48(*it)) { // packet.
if (!writer->WriteUInt64(lowest_time.ToMicroseconds())) {
return false; return false;
} }
}
if (!writer->WriteUInt48(frame.sent_info.least_unacked)) { for (++it; it != frame.received_info.received_packet_times.end(); ++it) {
QuicPacketSequenceNumber sequence_delta = it->first - lowest_sequence;
if (!writer->WriteBytes(&sequence_delta, 1)) {
return false; return false;
} }
size_t num_non_retransmiting_packets = int32 time_delta_us = it->second.Subtract(lowest_time).ToMicroseconds();
frame.sent_info.non_retransmiting.size(); if (!writer->WriteBytes(&time_delta_us, sizeof(time_delta_us))) {
if (!writer->WriteBytes(&num_non_retransmiting_packets, 1)) {
return false; return false;
} }
}
}
it = frame.sent_info.non_retransmiting.begin(); if (!writer->WriteUInt48(frame.sent_info.least_unacked)) {
while (it != frame.sent_info.non_retransmiting.end()) {
if (!writer->WriteUInt48(*it)) {
return false; return false;
} }
++it;
}
if (!writer->WriteBytes(&frame.congestion_info.type, 1)) { if (!writer->WriteBytes(&frame.congestion_info.type, 1)) {
return false; return false;
......
This diff is collapsed.
...@@ -3,8 +3,10 @@ ...@@ -3,8 +3,10 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "net/quic/quic_protocol.h" #include "net/quic/quic_protocol.h"
#include "base/stl_util.h"
using base::StringPiece; using base::StringPiece;
using std::map;
using std::ostream; using std::ostream;
namespace net { namespace net {
...@@ -21,30 +23,87 @@ QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id, ...@@ -21,30 +23,87 @@ QuicStreamFrame::QuicStreamFrame(QuicStreamId stream_id,
data(data) { data(data) {
} }
ReceivedPacketInfo::ReceivedPacketInfo() {} // TODO(ianswett): Initializing largest_received to 0 should not be necessary.
ReceivedPacketInfo::ReceivedPacketInfo() : largest_received(0) {}
ReceivedPacketInfo::~ReceivedPacketInfo() {} ReceivedPacketInfo::~ReceivedPacketInfo() {}
void ReceivedPacketInfo::RecordAck(QuicPacketSequenceNumber sequence_number,
QuicTime time) {
DCHECK(!ContainsAck(sequence_number));
received_packet_times[sequence_number] = time;
if (largest_received < sequence_number) {
largest_received = sequence_number;
}
}
bool ReceivedPacketInfo::ContainsAck(
QuicPacketSequenceNumber sequence_number) const {
return ContainsKey(received_packet_times, sequence_number);
}
void ReceivedPacketInfo::ClearAcksBefore(
QuicPacketSequenceNumber least_unacked) {
for (QuicPacketSequenceNumber i = received_packet_times.begin()->first;
i < least_unacked; ++i) {
received_packet_times.erase(i);
}
}
SentPacketInfo::SentPacketInfo() {} SentPacketInfo::SentPacketInfo() {}
SentPacketInfo::~SentPacketInfo() {} SentPacketInfo::~SentPacketInfo() {}
QuicAckFrame::QuicAckFrame(QuicPacketSequenceNumber largest_received,
QuicTime time_received,
QuicPacketSequenceNumber least_unacked) {
received_info.largest_received = largest_received;
for (QuicPacketSequenceNumber seq_num = 1;
seq_num <= largest_received; ++seq_num) {
received_info.RecordAck(seq_num, time_received);
}
sent_info.least_unacked = least_unacked;
congestion_info.type = kNone;
}
ostream& operator<<(ostream& os, const QuicAckFrame& s) { ostream& operator<<(ostream& os, const QuicAckFrame& s) {
os << "largest_received: " << s.received_info.largest_received os << "sent info { least_waiting: " << s.sent_info.least_unacked << " } "
<< " time: " << s.received_info.time_received.ToMicroseconds() << "received info { largest_received: "
<< " missing: "; << s.received_info.largest_received
for (SequenceSet::const_iterator it = s.received_info.missing_packets.begin(); << " received packets: [ ";
it != s.received_info.missing_packets.end(); ++it) { for (map<QuicPacketSequenceNumber, QuicTime>::const_iterator it =
os << *it << " "; s.received_info.received_packet_times.begin();
it != s.received_info.received_packet_times.end(); ++it) {
os << it->first << "@" << it->second.ToMilliseconds() << " ";
} }
os << " least_waiting: " << s.sent_info.least_unacked os << "] } congestion info { type: " << s.congestion_info.type;
<< " no_retransmit: "; switch (s.congestion_info.type) {
for (SequenceSet::const_iterator it = s.sent_info.non_retransmiting.begin(); case kNone:
it != s.sent_info.non_retransmiting.end(); ++it) { break;
os << *it << " "; case kInterArrival: {
const CongestionFeedbackMessageInterArrival& inter_arrival =
s.congestion_info.inter_arrival;
os << " accumulated_number_of_lost_packets: "
<< inter_arrival.accumulated_number_of_lost_packets;
os << " offset_time: " << inter_arrival.offset_time;
os << " delta_time: " << inter_arrival.delta_time;
break;
}
case kFixRate: {
os << " bitrate_in_bytes_per_second: "
<< s.congestion_info.fix_rate.bitrate_in_bytes_per_second;
break;
}
case kTCP: {
const CongestionFeedbackMessageTCP& tcp = s.congestion_info.tcp;
os << " accumulated_number_of_lost_packets: "
<< tcp.accumulated_number_of_lost_packets;
os << " receive_window: " << tcp.receive_window;
break;
}
} }
os << "\n"; os << " }\n";
return os; return os;
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define NET_QUIC_QUIC_PROTOCOL_H_ #define NET_QUIC_QUIC_PROTOCOL_H_
#include <limits> #include <limits>
#include <map>
#include <ostream> #include <ostream>
#include <utility> #include <utility>
#include <vector> #include <vector>
...@@ -168,14 +169,16 @@ typedef base::hash_set<QuicPacketSequenceNumber> SequenceSet; ...@@ -168,14 +169,16 @@ typedef base::hash_set<QuicPacketSequenceNumber> SequenceSet;
struct NET_EXPORT_PRIVATE ReceivedPacketInfo { struct NET_EXPORT_PRIVATE ReceivedPacketInfo {
ReceivedPacketInfo(); ReceivedPacketInfo();
~ReceivedPacketInfo(); ~ReceivedPacketInfo();
void RecordAck(QuicPacketSequenceNumber sequence_number, QuicTime time);
bool ContainsAck(QuicPacketSequenceNumber sequence_number) const;
void ClearAcksBefore(QuicPacketSequenceNumber least_unacked);
// The highest packet sequence number we've received from the peer. // The highest packet sequence number we've received from the peer.
QuicPacketSequenceNumber largest_received; QuicPacketSequenceNumber largest_received;
// The time at which we received the above packet.
QuicTime time_received; // The set of all received packets and their arrival times.
// The set of packets which we're expecting and have not received. std::map<QuicPacketSequenceNumber, QuicTime> received_packet_times;
// This includes any packets between the lowest and largest_received
// which we have neither seen nor been informed are non-retransmitting.
SequenceSet missing_packets;
}; };
struct NET_EXPORT_PRIVATE SentPacketInfo { struct NET_EXPORT_PRIVATE SentPacketInfo {
...@@ -183,9 +186,6 @@ struct NET_EXPORT_PRIVATE SentPacketInfo { ...@@ -183,9 +186,6 @@ struct NET_EXPORT_PRIVATE SentPacketInfo {
~SentPacketInfo(); ~SentPacketInfo();
// The lowest packet we've sent which is unacked, and we expect an ack for. // The lowest packet we've sent which is unacked, and we expect an ack for.
QuicPacketSequenceNumber least_unacked; QuicPacketSequenceNumber least_unacked;
// The set of packets between least_unacked and the last packet we have sent
// which we will not resend.
SequenceSet non_retransmiting;
}; };
// Defines for all types of congestion feedback that will be negotiated in QUIC, // Defines for all types of congestion feedback that will be negotiated in QUIC,
...@@ -241,14 +241,11 @@ struct NET_EXPORT_PRIVATE CongestionInfo { ...@@ -241,14 +241,11 @@ struct NET_EXPORT_PRIVATE CongestionInfo {
struct NET_EXPORT_PRIVATE QuicAckFrame { struct NET_EXPORT_PRIVATE QuicAckFrame {
QuicAckFrame() {} QuicAckFrame() {}
// Testing convenience method to construct a QuicAckFrame with all packets
// from least_unacked to largest_received acked at time_received.
QuicAckFrame(QuicPacketSequenceNumber largest_received, QuicAckFrame(QuicPacketSequenceNumber largest_received,
QuicTime time_received, QuicTime time_received,
QuicPacketSequenceNumber least_unacked) { QuicPacketSequenceNumber least_unacked);
received_info.largest_received = largest_received;
received_info.time_received = time_received;
sent_info.least_unacked = least_unacked;
congestion_info.type = kNone;
}
NET_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os, NET_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
const QuicAckFrame& s); const QuicAckFrame& s);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment