summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-18 04:52:34 +0000
committerrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-18 04:52:34 +0000
commitc068020aaff82bcc4f36ff7a65f1f2fe4adef7b7 (patch)
tree1f0f284d51b9b994b89ef3a4407bea8d9ec53d71
parent1f6a0aa92f0206545223d1c830b0867f01f273d0 (diff)
downloadchromium_src-c068020aaff82bcc4f36ff7a65f1f2fe4adef7b7.zip
chromium_src-c068020aaff82bcc4f36ff7a65f1f2fe4adef7b7.tar.gz
chromium_src-c068020aaff82bcc4f36ff7a65f1f2fe4adef7b7.tar.bz2
Land Recent QUIC Changes.
Cleanup. Saner QuicConnectionTest around entropy hashes; initialize all fields in QuicAckFrame. Merge internal change: 58299852 https://codereview.chromium.org/107573005/ QUIC Cleanup to use GetRetransmissionTime() instead of GetRetransmissionDelay() in SentPacketManager to allow the SentPacketManager more future control over the retransmission timer. Merge internal change: 58289241 https://codereview.chromium.org/116953002/ Added GetIncomingReliableStream method to QuicSessionPeer and other cosmetic changes. This is part of "Change the ownership model for ...QuicStream and QuicFasterStatsGatherer" internal change. Merge internal change: 58281240 https://codereview.chromium.org/114973006/ QuicSentPacketManager cleanup CL to move the handling of acks into one place. Merge internal change: 58181919 https://codereview.chromium.org/115933004/ R=rch@chromium.org Review URL: https://codereview.chromium.org/100543004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241489 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/quic/congestion_control/inter_arrival_sender_test.cc2
-rw-r--r--net/quic/congestion_control/send_algorithm_interface.h9
-rw-r--r--net/quic/quic_connection.cc59
-rw-r--r--net/quic/quic_connection.h46
-rw-r--r--net/quic/quic_connection_test.cc246
-rw-r--r--net/quic/quic_framer.cc2
-rw-r--r--net/quic/quic_http_stream_test.cc2
-rw-r--r--net/quic/quic_protocol.cc10
-rw-r--r--net/quic/quic_sent_packet_manager.cc144
-rw-r--r--net/quic/quic_sent_packet_manager.h46
-rw-r--r--net/quic/quic_sent_packet_manager_test.cc222
-rw-r--r--net/quic/test_tools/quic_sent_packet_manager_peer.cc6
-rw-r--r--net/quic/test_tools/quic_sent_packet_manager_peer.h3
-rw-r--r--net/quic/test_tools/quic_session_peer.cc7
-rw-r--r--net/quic/test_tools/quic_session_peer.h3
-rw-r--r--net/quic/test_tools/reliable_quic_stream_peer.cc5
-rw-r--r--net/quic/test_tools/reliable_quic_stream_peer.h1
-rw-r--r--net/tools/quic/quic_server_session.h4
18 files changed, 351 insertions, 466 deletions
diff --git a/net/quic/congestion_control/inter_arrival_sender_test.cc b/net/quic/congestion_control/inter_arrival_sender_test.cc
index fe8dd3c..7d9c39c 100644
--- a/net/quic/congestion_control/inter_arrival_sender_test.cc
+++ b/net/quic/congestion_control/inter_arrival_sender_test.cc
@@ -41,7 +41,7 @@ class InterArrivalSenderTest : public ::testing::Test {
QuicByteCount bytes_in_packet = kDefaultMaxPacketSize;
sent_packets_[sequence_number_] =
new class SendAlgorithmInterface::SentPacket(
- bytes_in_packet, send_clock_.Now(), HAS_RETRANSMITTABLE_DATA);
+ bytes_in_packet, send_clock_.Now());
sender_.OnPacketSent(send_clock_.Now(), sequence_number_, bytes_in_packet,
NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
diff --git a/net/quic/congestion_control/send_algorithm_interface.h b/net/quic/congestion_control/send_algorithm_interface.h
index 87a5f9c..44c943f 100644
--- a/net/quic/congestion_control/send_algorithm_interface.h
+++ b/net/quic/congestion_control/send_algorithm_interface.h
@@ -24,19 +24,13 @@ class NET_EXPORT_PRIVATE SendAlgorithmInterface {
public:
class SentPacket {
public:
- SentPacket(QuicByteCount bytes,
- QuicTime timestamp,
- HasRetransmittableData has_retransmittable_data)
+ SentPacket(QuicByteCount bytes, QuicTime timestamp)
: bytes_sent_(bytes),
send_timestamp_(timestamp),
- has_retransmittable_data_(has_retransmittable_data),
nack_count_(0) {
}
QuicByteCount bytes_sent() const { return bytes_sent_; }
const QuicTime& send_timestamp() const { return send_timestamp_; }
- HasRetransmittableData has_retransmittable_data() const {
- return has_retransmittable_data_;
- }
size_t nack_count() const { return nack_count_; }
void Nack(size_t min_nacks) {
@@ -46,7 +40,6 @@ class NET_EXPORT_PRIVATE SendAlgorithmInterface {
private:
QuicByteCount bytes_sent_;
QuicTime send_timestamp_;
- HasRetransmittableData has_retransmittable_data_;
size_t nack_count_;
};
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index 51a83cc..5cc630d 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -506,12 +506,10 @@ void QuicConnection::ProcessAckFrame(const QuicAckFrame& incoming_ack) {
if (reset_retransmission_alarm) {
retransmission_alarm_->Cancel();
- // Reset the RTO and FEC alarms if the are unacked packets.
- if (sent_packet_manager_.HasUnackedPackets()) {
- QuicTime::Delta retransmission_delay =
- sent_packet_manager_.GetRetransmissionDelay();
- retransmission_alarm_->Set(
- clock_->ApproximateNow().Add(retransmission_delay));
+ QuicTime retransmission_time =
+ sent_packet_manager_.GetRetransmissionTime();
+ if (retransmission_time != QuicTime::Zero()) {
+ retransmission_alarm_->Set(retransmission_time);
}
}
}
@@ -1084,25 +1082,6 @@ bool QuicConnection::CanWrite(TransmissionType transmission_type,
return true;
}
-void QuicConnection::SetupRetransmissionAlarm(
- QuicPacketSequenceNumber sequence_number) {
- if (!sent_packet_manager_.HasRetransmittableFrames(sequence_number)) {
- DVLOG(1) << ENDPOINT << "Will not retransmit packet " << sequence_number;
- return;
- }
-
- // Do not set the retransmission alarm if we're already handling one, since
- // it will be reset when OnRetransmissionTimeout completes.
- if (retransmission_alarm_->IsSet()) {
- return;
- }
-
- QuicTime::Delta retransmission_delay =
- sent_packet_manager_.GetRetransmissionDelay();
- retransmission_alarm_->Set(
- clock_->ApproximateNow().Add(retransmission_delay));
-}
-
bool QuicConnection::WritePacket(EncryptionLevel level,
QuicPacketSequenceNumber sequence_number,
QuicPacket* packet,
@@ -1297,13 +1276,6 @@ bool QuicConnection::OnPacketSent(WriteResult result) {
DVLOG(1) << ENDPOINT << "time of last sent packet: "
<< now.ToDebuggingValue();
- // Set the retransmit alarm only when we have sent the packet to the client
- // and not when it goes to the pending queue, otherwise we will end up adding
- // an entry to retransmission_timeout_ every time we attempt a write.
- if (retransmittable == HAS_RETRANSMITTABLE_DATA || is_fec_packet) {
- SetupRetransmissionAlarm(sequence_number);
- }
-
// TODO(ianswett): Change the sequence number length and other packet creator
// options by a more explicit API than setting a struct value directly.
packet_creator_.UpdateSequenceNumberLength(
@@ -1314,6 +1286,19 @@ bool QuicConnection::OnPacketSent(WriteResult result) {
sent_packet_manager_.OnPacketSent(sequence_number, now, length,
transmission_type, retransmittable);
+ // Set the retransmit alarm only when we have sent the packet to the client
+ // and not when it goes to the pending queue, otherwise we will end up adding
+ // an entry to retransmission_timeout_ every time we attempt a write.
+ // Do not set the retransmission alarm if we're already handling one, since
+ // it will be reset when OnRetransmissionTimeout completes.
+ if ((retransmittable == HAS_RETRANSMITTABLE_DATA || is_fec_packet) &&
+ !retransmission_alarm_->IsSet()) {
+ QuicTime retransmission_time =
+ sent_packet_manager_.GetRetransmissionTime();
+ DCHECK(retransmission_time != QuicTime::Zero());
+ retransmission_alarm_->Set(retransmission_time);
+ }
+
stats_.bytes_sent += result.bytes_written;
++stats_.packets_sent;
@@ -1399,11 +1384,11 @@ void QuicConnection::OnRetransmissionTimeout() {
WriteIfNotBlocked();
// Ensure the retransmission alarm is always set if there are unacked packets.
- if (sent_packet_manager_.HasUnackedPackets() && !HasQueuedData() &&
- !retransmission_alarm_->IsSet()) {
- QuicTime rto_timeout = clock_->ApproximateNow().Add(
- sent_packet_manager_.GetRetransmissionDelay());
- retransmission_alarm_->Set(rto_timeout);
+ if (!HasQueuedData() && !retransmission_alarm_->IsSet()) {
+ QuicTime rto_timeout = sent_packet_manager_.GetRetransmissionTime();
+ if (rto_timeout != QuicTime::Zero()) {
+ retransmission_alarm_->Set(rto_timeout);
+ }
}
}
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h
index beb8985..b7cf2d2 100644
--- a/net/quic/quic_connection.h
+++ b/net/quic/quic_connection.h
@@ -502,37 +502,6 @@ class NET_EXPORT_PRIVATE QuicConnection
Force forced;
};
- struct RetransmissionInfo {
- RetransmissionInfo(QuicPacketSequenceNumber sequence_number,
- QuicSequenceNumberLength sequence_number_length,
- QuicTime sent_time)
- : sequence_number(sequence_number),
- sequence_number_length(sequence_number_length),
- sent_time(sent_time),
- number_nacks(0),
- number_retransmissions(0) {
- }
-
- QuicPacketSequenceNumber sequence_number;
- QuicSequenceNumberLength sequence_number_length;
- QuicTime sent_time;
- size_t number_nacks;
- size_t number_retransmissions;
- };
-
- struct RetransmissionTime {
- RetransmissionTime(QuicPacketSequenceNumber sequence_number,
- const QuicTime& scheduled_time,
- bool for_fec)
- : sequence_number(sequence_number),
- scheduled_time(scheduled_time),
- for_fec(for_fec) { }
-
- QuicPacketSequenceNumber sequence_number;
- QuicTime scheduled_time;
- bool for_fec;
- };
-
struct PendingWrite {
PendingWrite(QuicPacketSequenceNumber sequence_number,
TransmissionType transmission_type,
@@ -555,27 +524,12 @@ class NET_EXPORT_PRIVATE QuicConnection
size_t length;
};
- class RetransmissionTimeComparator {
- public:
- bool operator()(const RetransmissionTime& lhs,
- const RetransmissionTime& rhs) const {
- DCHECK(lhs.scheduled_time.IsInitialized() &&
- rhs.scheduled_time.IsInitialized());
- return lhs.scheduled_time > rhs.scheduled_time;
- }
- };
-
typedef std::list<QueuedPacket> QueuedPacketList;
typedef std::map<QuicFecGroupNumber, QuicFecGroup*> FecGroupMap;
- typedef std::priority_queue<RetransmissionTime,
- std::vector<RetransmissionTime>,
- RetransmissionTimeComparator>
- RetransmissionTimeouts;
// Sends a version negotiation packet to the peer.
void SendVersionNegotiationPacket();
- void SetupRetransmissionAlarm(QuicPacketSequenceNumber sequence_number);
bool IsRetransmission(QuicPacketSequenceNumber sequence_number);
void SetupAbandonFecTimer(QuicPacketSequenceNumber sequence_number);
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index 39655d0..108cf04 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -31,6 +31,7 @@ using std::vector;
using testing::_;
using testing::AnyNumber;
using testing::ContainerEq;
+using testing::Contains;
using testing::DoAll;
using testing::InSequence;
using testing::InvokeWithoutArgs;
@@ -781,6 +782,40 @@ class QuicConnectionTest : public ::testing::TestWithParam<bool> {
return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2);
}
+ // Initialize a frame acknowledging all packets up to largest_observed.
+ const QuicAckFrame InitAckFrame(QuicPacketSequenceNumber largest_observed,
+ QuicPacketSequenceNumber least_unacked) {
+ QuicAckFrame frame(largest_observed, QuicTime::Zero(), least_unacked);
+ if (largest_observed > 0) {
+ frame.received_info.entropy_hash =
+ QuicConnectionPeer::GetSentEntropyHash(&connection_, largest_observed);
+ }
+ return frame;
+ }
+
+ // Explicitly nack a packet.
+ void NackPacket(QuicPacketSequenceNumber missing, QuicAckFrame* frame) {
+ frame->received_info.missing_packets.insert(missing);
+ frame->received_info.entropy_hash ^=
+ QuicConnectionPeer::GetSentEntropyHash(&connection_, missing);
+ if (missing > 1) {
+ frame->received_info.entropy_hash ^=
+ QuicConnectionPeer::GetSentEntropyHash(&connection_, missing - 1);
+ }
+ }
+
+ // Undo nacking a packet within the frame.
+ void AckPacket(QuicPacketSequenceNumber arrived, QuicAckFrame* frame) {
+ EXPECT_THAT(frame->received_info.missing_packets, Contains(arrived));
+ frame->received_info.missing_packets.erase(arrived);
+ frame->received_info.entropy_hash ^=
+ QuicConnectionPeer::GetSentEntropyHash(&connection_, arrived);
+ if (arrived > 1) {
+ frame->received_info.entropy_hash ^=
+ QuicConnectionPeer::GetSentEntropyHash(&connection_, arrived - 1);
+ }
+ }
+
QuicGuid guid_;
QuicFramer framer_;
QuicPacketCreator creator_;
@@ -892,7 +927,7 @@ TEST_F(QuicConnectionTest, PacketsOutOfOrderWithAdditionsAndLeastAwaiting) {
// awaiting' is 4. The connection should then realize 1 will not be
// retransmitted, and will remove it from the missing list.
creator_.set_sequence_number(5);
- QuicAckFrame frame(0, QuicTime::Zero(), 4);
+ QuicAckFrame frame = InitAckFrame(0, 4);
ProcessAckPacket(&frame);
// Force an ack to be sent.
@@ -914,12 +949,11 @@ TEST_F(QuicConnectionTest, TruncatedAck) {
SendStreamDataToPeer(1, "foo", i * 3, !kFin, NULL);
}
- QuicAckFrame frame(num_packets, QuicTime::Zero(), 1);
+ QuicAckFrame frame = InitAckFrame(num_packets, 1);
// Create an ack with 256 nacks, none adjacent to one another.
for (QuicPacketSequenceNumber i = 1; i <= 256; ++i) {
- frame.received_info.missing_packets.insert(i * 2);
+ NackPacket(i * 2, &frame);
}
- frame.received_info.entropy_hash = 0;
EXPECT_CALL(entropy_calculator_,
EntropyHash(511)).WillOnce(testing::Return(0));
EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(256);
@@ -933,8 +967,7 @@ TEST_F(QuicConnectionTest, TruncatedAck) {
EXPECT_GT(num_packets,
received_packet_manager->peer_largest_observed_packet());
- frame.received_info.missing_packets.erase(192);
- frame.received_info.entropy_hash = 2;
+ AckPacket(192, &frame);
// Removing one missing packet allows us to ack 192 and one more range.
EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(2);
@@ -962,7 +995,7 @@ TEST_F(QuicConnectionTest, AckReceiptCausesAckSendBadEntropy) {
testing::Return(QuicTime::Delta::Zero()));
// Skip a packet and then record an ack.
creator_.set_sequence_number(2);
- QuicAckFrame frame(0, QuicTime::Zero(), 3);
+ QuicAckFrame frame = InitAckFrame(0, 3);
ProcessAckPacket(&frame);
}
@@ -996,10 +1029,8 @@ TEST_F(QuicConnectionTest, AckReceiptCausesAckSend) {
Return(true)));
EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1);
connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
- QuicAckFrame frame(original, QuicTime::Zero(), 1);
- frame.received_info.missing_packets.insert(original);
- frame.received_info.entropy_hash = QuicConnectionPeer::GetSentEntropyHash(
- &connection_, original - 1);
+ QuicAckFrame frame = InitAckFrame(original, 1);
+ NackPacket(original, &frame);
// First nack triggers early retransmit.
QuicPacketSequenceNumber retransmission;
EXPECT_CALL(*send_algorithm_,
@@ -1009,11 +1040,8 @@ TEST_F(QuicConnectionTest, AckReceiptCausesAckSend) {
ProcessAckPacket(&frame);
- QuicAckFrame frame2(retransmission, QuicTime::Zero(), 1);
- frame2.received_info.missing_packets.insert(original);
- frame2.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, retransmission) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, original);
+ QuicAckFrame frame2 = InitAckFrame(retransmission, 1);
+ NackPacket(original, &frame2);
EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _));
ProcessAckPacket(&frame2);
@@ -1024,9 +1052,7 @@ TEST_F(QuicConnectionTest, AckReceiptCausesAckSend) {
ProcessAckPacket(&frame2);
// But an ack with no missing packets will not send an ack.
- frame2.received_info.missing_packets.clear();
- frame2.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, retransmission);
+ AckPacket(original, &frame2);
ProcessAckPacket(&frame2);
ProcessAckPacket(&frame2);
}
@@ -1040,13 +1066,13 @@ TEST_F(QuicConnectionTest, LeastUnackedLower) {
// Start out saying the least unacked is 2.
creator_.set_sequence_number(5);
- QuicAckFrame frame(0, QuicTime::Zero(), 2);
+ QuicAckFrame frame = InitAckFrame(0, 2);
ProcessAckPacket(&frame);
// Change it to 1, but lower the sequence number to fake out-of-order packets.
// This should be fine.
creator_.set_sequence_number(1);
- QuicAckFrame frame2(0, QuicTime::Zero(), 1);
+ QuicAckFrame frame2 = InitAckFrame(0, 1);
// The scheduler will not process out of order acks.
EXPECT_CALL(visitor_, OnCanWrite()).Times(0);
ProcessAckPacket(&frame2);
@@ -1068,16 +1094,14 @@ TEST_F(QuicConnectionTest, LargestObservedLower) {
EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(2);
// Start out saying the largest observed is 2.
- QuicAckFrame frame(2, QuicTime::Zero(), 0);
- frame.received_info.entropy_hash = QuicConnectionPeer::GetSentEntropyHash(
- &connection_, 2);
- ProcessAckPacket(&frame);
+ QuicAckFrame frame1 = InitAckFrame(1, 0);
+ QuicAckFrame frame2 = InitAckFrame(2, 0);
+ ProcessAckPacket(&frame2);
// Now change it to 1, and it should cause a connection error.
- QuicAckFrame frame2(1, QuicTime::Zero(), 0);
EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_INVALID_ACK_DATA, false));
EXPECT_CALL(visitor_, OnCanWrite()).Times(0);
- ProcessAckPacket(&frame2);
+ ProcessAckPacket(&frame1);
}
TEST_F(QuicConnectionTest, AckUnsentData) {
@@ -1095,7 +1119,7 @@ TEST_F(QuicConnectionTest, AckAll) {
ProcessPacket(1);
creator_.set_sequence_number(1);
- QuicAckFrame frame1(0, QuicTime::Zero(), 1);
+ QuicAckFrame frame1 = InitAckFrame(0, 1);
ProcessAckPacket(&frame1);
}
@@ -1218,9 +1242,7 @@ TEST_F(QuicConnectionTest, BasicSending) {
EXPECT_EQ(1u, last_ack()->sent_info.least_unacked);
// Peer acks up to packet 3.
- QuicAckFrame frame(3, QuicTime::Zero(), 0);
- frame.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 3);
+ QuicAckFrame frame = InitAckFrame(3, 0);
ProcessAckPacket(&frame);
SendAckPacketToPeer(); // Packet 6
@@ -1229,9 +1251,7 @@ TEST_F(QuicConnectionTest, BasicSending) {
EXPECT_EQ(4u, last_ack()->sent_info.least_unacked);
// Peer acks up to packet 4, the last packet.
- QuicAckFrame frame2(6, QuicTime::Zero(), 0);
- frame2.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 6);
+ QuicAckFrame frame2 = InitAckFrame(6, 0);
ProcessAckPacket(&frame2); // Acks don't instigate acks.
// Verify that we did not send an ack.
@@ -1248,7 +1268,7 @@ TEST_F(QuicConnectionTest, BasicSending) {
SendStreamDataToPeer(1, "eep", 6, !kFin, &last_packet); // Packet 8
EXPECT_EQ(8u, last_packet);
SendAckPacketToPeer(); // Packet 9
- EXPECT_EQ(8u, last_ack()->sent_info.least_unacked);
+ EXPECT_EQ(7u, last_ack()->sent_info.least_unacked);
}
TEST_F(QuicConnectionTest, FECSending) {
@@ -1318,19 +1338,14 @@ TEST_F(QuicConnectionTest, DontAbandonAckedFEC) {
connection_.SendStreamDataWithString(1, "foo", 3, !kFin, NULL);
connection_.SendStreamDataWithString(1, "foo", 6, !kFin, NULL);
- QuicAckFrame ack_fec(2, QuicTime::Zero(), 1);
+ QuicAckFrame ack_fec = InitAckFrame(2, 1);
// Data packet missing.
// TODO(ianswett): Note that this is not a sensible ack, since if the FEC was
// received, it would cause the covered packet to be acked as well.
- ack_fec.received_info.missing_packets.insert(1);
- ack_fec.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 1);
+ NackPacket(1, &ack_fec);
EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(1);
-
ProcessAckPacket(&ack_fec);
-
clock_.AdvanceTime(DefaultRetransmissionTime());
// Don't abandon the acked FEC packet, but it will abandon 2 the subsequent
@@ -1354,16 +1369,10 @@ TEST_F(QuicConnectionTest, DontAbandonAllFEC) {
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
connection_.SendStreamDataWithString(1, "foo", 6, !kFin, NULL);
- QuicAckFrame ack_fec(5, QuicTime::Zero(), 1);
+ QuicAckFrame ack_fec = InitAckFrame(5, 1);
// Ack all data packets, but no fec packets.
- ack_fec.received_info.missing_packets.insert(2);
- ack_fec.received_info.missing_packets.insert(4);
- ack_fec.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 5) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 4) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 3) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 1);
+ NackPacket(2, &ack_fec);
+ NackPacket(4, &ack_fec);
// Lose the first FEC packet and ack the three data packets.
EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(3);
@@ -1520,7 +1529,7 @@ TEST_F(QuicConnectionTest, FramePackingAckResponse) {
// Process an ack to cause the visitor's OnCanWrite to be invoked.
creator_.set_sequence_number(2);
- QuicAckFrame ack_one(0, QuicTime::Zero(), 0);
+ QuicAckFrame ack_one = InitAckFrame(0, 0);
ProcessAckPacket(&ack_one);
EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -1644,21 +1653,15 @@ TEST_F(QuicConnectionTest, RetransmitOnNack) {
// Peer acks one but not two or three. Right now we only retransmit on
// explicit nack, so it should not trigger a retransmission.
- QuicAckFrame ack_one(1, QuicTime::Zero(), 0);
- ack_one.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 1);
+ QuicAckFrame ack_one = InitAckFrame(1, 0);
ProcessAckPacket(&ack_one);
ProcessAckPacket(&ack_one);
ProcessAckPacket(&ack_one);
// Peer acks up to 3 with two explicitly missing.
// Early retransmit causes 2 to be retransmitted on the first ack.
- QuicAckFrame nack_two(3, QuicTime::Zero(), 0);
- nack_two.received_info.missing_packets.insert(2);
- nack_two.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 3) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 1);
+ QuicAckFrame nack_two = InitAckFrame(3, 0);
+ NackPacket(2, &nack_two);
// The third nack should trigger a retransmission.
EXPECT_CALL(*send_algorithm_,
OnPacketSent(_, _, second_packet_size - kQuicVersionSize,
@@ -1679,21 +1682,15 @@ TEST_F(QuicConnectionTest, DiscardRetransmit) {
// Peer acks one but not two or three. Right now we only retransmit on
// explicit nack, so it should not trigger a retransmission.
- QuicAckFrame ack_one(1, QuicTime::Zero(), 0);
- ack_one.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 1);
+ QuicAckFrame ack_one = InitAckFrame(1, 0);
ProcessAckPacket(&ack_one);
ProcessAckPacket(&ack_one);
ProcessAckPacket(&ack_one);
// Peer acks up to 3 with two explicitly missing. Two nacks should cause no
// change.
- QuicAckFrame nack_two(3, QuicTime::Zero(), 0);
- nack_two.received_info.missing_packets.insert(2);
- nack_two.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 3) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 1);
+ QuicAckFrame nack_two = InitAckFrame(3, 0);
+ NackPacket(2, &nack_two);
// The first nack should trigger a fast retransmission, but we'll be
// write blocked, so the packet will be queued.
writer_->set_blocked(true);
@@ -1702,9 +1699,7 @@ TEST_F(QuicConnectionTest, DiscardRetransmit) {
EXPECT_EQ(1u, connection_.NumQueuedPackets());
// Now, ack the previous transmission.
- QuicAckFrame ack_all(3, QuicTime::Zero(), 0);
- ack_all.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 3);
+ QuicAckFrame ack_all = InitAckFrame(3, 0);
ProcessAckPacket(&ack_all);
// Unblock the socket and attempt to send the queued packets. However,
@@ -1729,10 +1724,8 @@ TEST_F(QuicConnectionTest, RetransmitNackedLargestObserved) {
Return(true)));
EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1);
connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
- QuicAckFrame frame(1, QuicTime::Zero(), largest_observed);
- frame.received_info.missing_packets.insert(largest_observed);
- frame.received_info.entropy_hash = QuicConnectionPeer::GetSentEntropyHash(
- &connection_, largest_observed - 1);
+ QuicAckFrame frame = InitAckFrame(1, largest_observed);
+ NackPacket(largest_observed, &frame);
// The first nack should retransmit the largest observed packet.
EXPECT_CALL(*send_algorithm_,
OnPacketSent(_, _, packet_size - kQuicVersionSize,
@@ -1802,15 +1795,11 @@ TEST_F(QuicConnectionTest, LimitPacketsPerNack) {
}
// Ack 15, nack 1-14.
- QuicAckFrame nack(15, QuicTime::Zero(), 0);
+ QuicAckFrame nack = InitAckFrame(15, 0);
for (int i = 1; i < 15; ++i) {
- nack.received_info.missing_packets.insert(i);
+ NackPacket(i, &nack);
}
- nack.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 15) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 14);
-
// 13 packets have been NACK'd 3 times, but we limit retransmissions to 2.
EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2);
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
@@ -1839,34 +1828,26 @@ TEST_F(QuicConnectionTest, MultipleAcks) {
EXPECT_EQ(6u, last_packet);
// Client will ack packets 1, 2, [!3], 4, 5.
- QuicAckFrame frame1(5, QuicTime::Zero(), 0);
- frame1.received_info.missing_packets.insert(3);
- frame1.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 5) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 3) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 2);
-
+ QuicAckFrame frame1 = InitAckFrame(5, 0);
+ NackPacket(3, &frame1);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-
ProcessAckPacket(&frame1);
// Now the client implicitly acks 3, and explicitly acks 6.
- QuicAckFrame frame2(6, QuicTime::Zero(), 0);
- frame2.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 6);
-
+ QuicAckFrame frame2 = InitAckFrame(6, 0);
ProcessAckPacket(&frame2);
}
TEST_F(QuicConnectionTest, DontLatchUnackedPacket) {
EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(1);
SendStreamDataToPeer(1, "foo", 0, !kFin, NULL); // Packet 1;
+ // From now on, we send acks, so the send algorithm won't save them.
+ ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .WillByDefault(Return(false));
SendAckPacketToPeer(); // Packet 2
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- QuicAckFrame frame(1, QuicTime::Zero(), 0);
- frame.received_info.entropy_hash = QuicConnectionPeer::GetSentEntropyHash(
- &connection_, 1);
+ QuicAckFrame frame = InitAckFrame(1, 0);
ProcessAckPacket(&frame);
// Verify that our internal state has least-unacked as 3.
@@ -1881,8 +1862,12 @@ TEST_F(QuicConnectionTest, DontLatchUnackedPacket) {
// Check that the outgoing ack had its sequence number as least_unacked.
EXPECT_EQ(3u, last_ack()->sent_info.least_unacked);
+ ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .WillByDefault(Return(true));
SendStreamDataToPeer(1, "bar", 3, false, NULL); // Packet 4
EXPECT_EQ(4u, outgoing_ack()->sent_info.least_unacked);
+ ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .WillByDefault(Return(false));
SendAckPacketToPeer(); // Packet 5
EXPECT_EQ(4u, last_ack()->sent_info.least_unacked);
}
@@ -2175,15 +2160,10 @@ TEST_F(QuicConnectionTest, RetransmissionCountCalculation) {
.Times(AnyNumber());
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, NACK_RETRANSMISSION, _))
.WillOnce(DoAll(SaveArg<1>(&nack_sequence_number), Return(true)));
- QuicAckFrame ack(rto_sequence_number, QuicTime::Zero(), 0);
+ QuicAckFrame ack = InitAckFrame(rto_sequence_number, 0);
// Ack the retransmitted packet.
- ack.received_info.missing_packets.insert(original_sequence_number);
- ack.received_info.missing_packets.insert(rto_sequence_number);
- ack.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_,
- rto_sequence_number - 1) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_,
- original_sequence_number);
+ NackPacket(original_sequence_number, &ack);
+ NackPacket(rto_sequence_number, &ack);
for (int i = 0; i < 3; i++) {
ProcessAckPacket(&ack);
}
@@ -2221,9 +2201,7 @@ TEST_F(QuicConnectionTest, DelayRTOWithAckReceipt) {
// packet to delay the RTO.
clock_.AdvanceTime(DefaultRetransmissionTime());
EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(1);
- QuicAckFrame ack(1, QuicTime::Zero(), 0);
- ack.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 1);
+ QuicAckFrame ack = InitAckFrame(1, 0);
ProcessAckPacket(&ack);
EXPECT_TRUE(retransmission_alarm->IsSet());
@@ -2276,7 +2254,7 @@ TEST_F(QuicConnectionTest, CloseFecGroup) {
ASSERT_EQ(1u, connection_.NumFecGroups());
// Now send non-fec protected ack packet and close the group.
- QuicAckFrame frame(0, QuicTime::Zero(), 5);
+ QuicAckFrame frame = InitAckFrame(0, 5);
creator_.set_sequence_number(4);
ProcessAckPacket(&frame);
ASSERT_EQ(0u, connection_.NumFecGroups());
@@ -2504,7 +2482,7 @@ TEST_F(QuicConnectionTest, SendSchedulerDelayThenAckAndSend) {
// Now send non-retransmitting information, that we're not going to
// retransmit 3. The far end should stop waiting for it.
- QuicAckFrame frame(0, QuicTime::Zero(), 1);
+ QuicAckFrame frame = InitAckFrame(0, 1);
EXPECT_CALL(*send_algorithm_,
TimeUntilSend(_, NOT_RETRANSMISSION, _, _)).WillRepeatedly(
testing::Return(QuicTime::Delta::Zero()));
@@ -2529,7 +2507,7 @@ TEST_F(QuicConnectionTest, SendSchedulerDelayThenAckAndHold) {
// Now send non-retransmitting information, that we're not going to
// retransmit 3. The far end should stop waiting for it.
- QuicAckFrame frame(0, QuicTime::Zero(), 1);
+ QuicAckFrame frame = InitAckFrame(0, 1);
EXPECT_CALL(*send_algorithm_,
TimeUntilSend(_, NOT_RETRANSMISSION, _, _)).WillOnce(
testing::Return(QuicTime::Delta::FromMicroseconds(1)));
@@ -2715,7 +2693,7 @@ TEST_F(QuicConnectionTest, InvalidPacket) {
}
TEST_F(QuicConnectionTest, MissingPacketsBeforeLeastUnacked) {
- QuicAckFrame ack(0, QuicTime::Zero(), 4);
+ QuicAckFrame ack = InitAckFrame(0, 4);
// Set the sequence number of the ack packet to be least unacked (4).
creator_.set_sequence_number(3);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
@@ -2741,7 +2719,7 @@ TEST_F(QuicConnectionTest, UpdateEntropyForReceivedPackets) {
ProcessDataPacket(4, 1, !kEntropyFlag);
EXPECT_EQ(34u, outgoing_ack()->received_info.entropy_hash);
// Make 4th packet my least unacked, and update entropy for 2, 3 packets.
- QuicAckFrame ack(0, QuicTime::Zero(), 4);
+ QuicAckFrame ack = InitAckFrame(0, 4);
QuicPacketEntropyHash kRandomEntropyHash = 129u;
ack.sent_info.entropy_hash = kRandomEntropyHash;
creator_.set_sequence_number(5);
@@ -2764,7 +2742,7 @@ TEST_F(QuicConnectionTest, UpdateEntropyHashUptoCurrentPacket) {
creator_.set_sequence_number(22);
QuicPacketEntropyHash kRandomEntropyHash = 85u;
// Current packet is the least unacked packet.
- QuicAckFrame ack(0, QuicTime::Zero(), 23);
+ QuicAckFrame ack = InitAckFrame(0, 23);
ack.sent_info.entropy_hash = kRandomEntropyHash;
QuicPacketEntropyHash ack_entropy_hash = ProcessAckPacket(&ack);
EXPECT_EQ((kRandomEntropyHash + ack_entropy_hash),
@@ -3034,14 +3012,9 @@ TEST_F(QuicConnectionTest, CheckSendStats) {
connection_.GetRetransmissionAlarm()->Fire();
// Retransmit due to explicit nacks.
- QuicAckFrame nack_three(4, QuicTime::Zero(), 0);
- nack_three.received_info.missing_packets.insert(3);
- nack_three.received_info.missing_packets.insert(1);
- nack_three.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 4) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 3) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 1);
+ QuicAckFrame nack_three = InitAckFrame(4, 0);
+ NackPacket(3, &nack_three);
+ NackPacket(1, &nack_three);
QuicFrame frame(&nack_three);
EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(1);
EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(1);
@@ -3222,9 +3195,7 @@ TEST_F(QuicConnectionTest, AckNotifierTriggerCallback) {
// Process an ACK from the server which should trigger the callback.
EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(1);
- QuicAckFrame frame(1, QuicTime::Zero(), 0);
- frame.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 1);
+ QuicAckFrame frame = InitAckFrame(1, 0);
ProcessAckPacket(&frame);
}
@@ -3247,11 +3218,8 @@ TEST_F(QuicConnectionTest, AckNotifierFailToTriggerCallback) {
// Now we receive ACK for packets 2 and 3, but importantly missing packet 1
// which we registered to be notified about.
- QuicAckFrame frame(3, QuicTime::Zero(), 0);
- frame.received_info.missing_packets.insert(1);
- frame.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 3) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 1);
+ QuicAckFrame frame = InitAckFrame(3, 0);
+ NackPacket(1, &frame);
EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _));
EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _));
ProcessAckPacket(&frame);
@@ -3274,12 +3242,8 @@ TEST_F(QuicConnectionTest, AckNotifierCallbackAfterRetransmission) {
connection_.SendStreamDataWithString(1, "qux", 0, !kFin, NULL);
// Now we receive ACK for packets 1, 3, and 4, which invokes fast retransmit.
- QuicAckFrame frame(4, QuicTime::Zero(), 0);
- frame.received_info.missing_packets.insert(2);
- frame.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 4) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 1);
+ QuicAckFrame frame = InitAckFrame(4, 0);
+ NackPacket(2, &frame);
EXPECT_CALL(*send_algorithm_, OnPacketLost(2, _));
EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(2, _));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
@@ -3287,9 +3251,7 @@ TEST_F(QuicConnectionTest, AckNotifierCallbackAfterRetransmission) {
// Now we get an ACK for packet 5 (retransmitted packet 2), which should
// trigger the callback.
- QuicAckFrame second_ack_frame(5, QuicTime::Zero(), 0);
- second_ack_frame.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 5);
+ QuicAckFrame second_ack_frame = InitAckFrame(5, 0);
ProcessAckPacket(&second_ack_frame);
}
@@ -3313,9 +3275,7 @@ TEST_F(QuicConnectionTest, AckNotifierCallbackAfterFECRecovery) {
// Should recover the Ack packet and trigger the notification callback.
QuicFrames frames;
- QuicAckFrame ack_frame(1, QuicTime::Zero(), 0);
- ack_frame.received_info.entropy_hash =
- QuicConnectionPeer::GetSentEntropyHash(&connection_, 1);
+ QuicAckFrame ack_frame = InitAckFrame(1, 0);
frames.push_back(QuicFrame(&ack_frame));
// Dummy stream frame to satisfy expectations set elsewhere.
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
index cc02882..610dc57 100644
--- a/net/quic/quic_framer.cc
+++ b/net/quic/quic_framer.cc
@@ -2070,7 +2070,7 @@ bool QuicFramer::AppendGoAwayFramePayload(const QuicGoAwayFrame& frame,
}
bool QuicFramer::RaiseError(QuicErrorCode error) {
- DVLOG(1) << detailed_error_;
+ DVLOG(1) << "Error detail: " << detailed_error_;
set_error(error);
visitor_->OnError(this);
reader_.reset(NULL);
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc
index 97ae972..ad14ee1 100644
--- a/net/quic/quic_http_stream_test.cc
+++ b/net/quic/quic_http_stream_test.cc
@@ -190,7 +190,7 @@ class QuicHttpStreamTest : public ::testing::TestWithParam<bool> {
EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _, _)).
Times(AnyNumber());
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+ OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
Return(QuicTime::Delta::Zero()));
EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)).
diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc
index cc37c11..e53daec 100644
--- a/net/quic/quic_protocol.cc
+++ b/net/quic/quic_protocol.cc
@@ -210,10 +210,10 @@ ostream& operator<<(ostream& os, const QuicPacketHeader& header) {
}
ReceivedPacketInfo::ReceivedPacketInfo()
- : largest_observed(0),
+ : entropy_hash(0),
+ largest_observed(0),
delta_time_largest_observed(QuicTime::Delta::Infinite()),
- is_truncated(false) {
-}
+ is_truncated(false) {}
ReceivedPacketInfo::~ReceivedPacketInfo() {}
@@ -231,7 +231,9 @@ void InsertMissingPacketsBetween(ReceivedPacketInfo* received_info,
}
}
-SentPacketInfo::SentPacketInfo() {}
+SentPacketInfo::SentPacketInfo()
+ : entropy_hash(0),
+ least_unacked(0) {}
SentPacketInfo::~SentPacketInfo() {}
diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc
index bda30c7..bb7f496 100644
--- a/net/quic/quic_sent_packet_manager.cc
+++ b/net/quic/quic_sent_packet_manager.cc
@@ -104,16 +104,14 @@ void QuicSentPacketManager::SetMaxPacketSize(QuicByteCount max_packet_size) {
send_algorithm_->SetMaxPacketSize(max_packet_size);
}
+// TODO(ianswett): Combine this method with OnPacketSent once packets are always
+// sent in order and the connection tracks RetransmittableFrames for longer.
void QuicSentPacketManager::OnSerializedPacket(
const SerializedPacket& serialized_packet) {
- if (serialized_packet.retransmittable_frames == NULL &&
- !serialized_packet.packet->is_fec_packet()) {
- // Don't track ack/congestion feedback packets.
- return;
+ if (serialized_packet.retransmittable_frames) {
+ ack_notifier_manager_.OnSerializedPacket(serialized_packet);
}
- ack_notifier_manager_.OnSerializedPacket(serialized_packet);
-
DCHECK(unacked_packets_.empty() ||
unacked_packets_.rbegin()->first < serialized_packet.sequence_number);
unacked_packets_[serialized_packet.sequence_number] =
@@ -130,6 +128,7 @@ void QuicSentPacketManager::OnRetransmittedPacket(
unacked_packets_.rbegin()->first < new_sequence_number);
pending_retransmissions_.erase(old_sequence_number);
+ // TODO(ianswett): Discard and lose the packet lazily instead of immediately.
UnackedPacketMap::iterator unacked_it =
unacked_packets_.find(old_sequence_number);
@@ -172,16 +171,9 @@ bool QuicSentPacketManager::OnIncomingAck(
bool new_least_unacked = !IsAwaitingPacket(received_info,
least_unacked_sent_before);
+ MaybeUpdateRTT(received_info, ack_receive_time);
HandleAckForSentPackets(received_info);
-
- SequenceNumberSet retransmission_packets =
- OnIncomingAckFrame(received_info, ack_receive_time);
-
- for (SequenceNumberSet::const_iterator it = retransmission_packets.begin();
- it != retransmission_packets.end(); ++it) {
- DCHECK(!ContainsKey(pending_packets_, *it));
- MarkForRetransmission(*it, NACK_RETRANSMISSION);
- }
+ MaybeRetransmitOnAckFrame(received_info, ack_receive_time);
if (new_least_unacked) {
consecutive_rto_count_ = 0;
@@ -192,7 +184,7 @@ bool QuicSentPacketManager::OnIncomingAck(
void QuicSentPacketManager::DiscardUnackedPacket(
QuicPacketSequenceNumber sequence_number) {
- MarkPacketReceivedByPeer(sequence_number);
+ MarkPacketHandled(sequence_number, NOT_RECEIVED_BY_PEER);
}
void QuicSentPacketManager::HandleAckForSentPackets(
@@ -216,7 +208,7 @@ void QuicSentPacketManager::HandleAckForSentPackets(
DVLOG(1) << ENDPOINT <<"Got an ack for packet " << sequence_number;
// If data is associated with the most recent transmission of this
// packet, then inform the caller.
- it = MarkPacketReceivedByPeer(sequence_number);
+ it = MarkPacketHandled(sequence_number, RECEIVED_BY_PEER);
// The AckNotifierManager is informed of every ACKed sequence number.
ack_notifier_manager_.OnPacketAcked(sequence_number);
@@ -287,29 +279,28 @@ void QuicSentPacketManager::RetransmitUnackedPackets(
// TODO(satyamshekhar): Think about congestion control here.
// Specifically, about the retransmission count of packets being sent
// proactively to achieve 0 (minimal) RTT.
- OnPacketAbandoned(unacked_it->first);
- if (!MarkForRetransmission(unacked_it->first, NACK_RETRANSMISSION)) {
+ if (unacked_it->second.retransmittable_frames) {
+ OnPacketAbandoned(unacked_it->first);
+ MarkForRetransmission(unacked_it->first, NACK_RETRANSMISSION);
+ } else {
DiscardUnackedPacket(unacked_it->first);
}
}
}
}
-bool QuicSentPacketManager::MarkForRetransmission(
+void QuicSentPacketManager::MarkForRetransmission(
QuicPacketSequenceNumber sequence_number,
TransmissionType transmission_type) {
DCHECK(ContainsKey(unacked_packets_, sequence_number));
- if (!HasRetransmittableFrames(sequence_number)) {
- return false;
- }
- // If it's already in the retransmission map, don't add it again, just let
- // the prior retransmission request win out.
+ DCHECK(HasRetransmittableFrames(sequence_number));
+ // TODO(ianswett): Currently the RTO can fire while there are pending NACK
+ // retransmissions for the same data, which is not ideal.
if (ContainsKey(pending_retransmissions_, sequence_number)) {
- return true;
+ return;
}
pending_retransmissions_[sequence_number] = transmission_type;
- return true;
}
bool QuicSentPacketManager::HasPendingRetransmissions() const {
@@ -347,10 +338,21 @@ bool QuicSentPacketManager::IsPreviousTransmission(
}
QuicSentPacketManager::UnackedPacketMap::iterator
-QuicSentPacketManager::MarkPacketReceivedByPeer(
- QuicPacketSequenceNumber sequence_number) {
+QuicSentPacketManager::MarkPacketHandled(
+ QuicPacketSequenceNumber sequence_number, ReceivedByPeer received_by_peer) {
DCHECK(ContainsKey(unacked_packets_, sequence_number));
+ // If this packet is pending, remove it and inform the send algorithm.
+ if (pending_packets_.erase(sequence_number)) {
+ size_t bytes_sent = packet_history_map_[sequence_number]->bytes_sent();
+ if (received_by_peer == RECEIVED_BY_PEER) {
+ send_algorithm_->OnPacketAcked(sequence_number, bytes_sent, rtt_sample_);
+ } else {
+ // It's been abandoned.
+ send_algorithm_->OnPacketAbandoned(sequence_number, bytes_sent);
+ }
+ }
+
// If this packet has never been retransmitted, then simply drop it.
UnackedPacketMap::const_iterator previous_it =
unacked_packets_.find(sequence_number);
@@ -470,18 +472,20 @@ void QuicSentPacketManager::OnPacketSent(
HasRetransmittableData has_retransmittable_data) {
DCHECK_LT(0u, sequence_number);
DCHECK(!ContainsKey(pending_packets_, sequence_number));
- if (ContainsKey(unacked_packets_, sequence_number)) {
- unacked_packets_[sequence_number].sent_time = sent_time;
- }
+ DCHECK(ContainsKey(unacked_packets_, sequence_number));
// Only track packets the send algorithm wants us to track.
if (!send_algorithm_->OnPacketSent(sent_time, sequence_number, bytes,
transmission_type,
has_retransmittable_data)) {
+ DCHECK(unacked_packets_[sequence_number].retransmittable_frames == NULL);
+ unacked_packets_.erase(sequence_number);
return;
}
- packet_history_map_[sequence_number] = new SendAlgorithmInterface::SentPacket(
- bytes, sent_time, has_retransmittable_data);
+
+ unacked_packets_[sequence_number].sent_time = sent_time;
+ packet_history_map_[sequence_number] =
+ new SendAlgorithmInterface::SentPacket(bytes, sent_time);
pending_packets_.insert(sequence_number);
CleanupPacketHistory();
}
@@ -492,23 +496,6 @@ void QuicSentPacketManager::OnRetransmissionTimeout() {
QuicTime::Delta retransmission_delay = GetRetransmissionDelay();
QuicTime max_send_time =
clock_->ApproximateNow().Subtract(retransmission_delay);
- for (SequenceNumberSet::iterator it = pending_packets_.begin();
- it != pending_packets_.end();) {
- QuicPacketSequenceNumber sequence_number = *it;
- DCHECK(ContainsKey(packet_history_map_, sequence_number));
- DCHECK(ContainsKey(unacked_packets_, sequence_number));
- const TransmissionInfo& transmission_info =
- unacked_packets_.find(sequence_number)->second;
- // Abandon retransmittable packet and old non-retransmittable packets.
- if (transmission_info.retransmittable_frames ||
- transmission_info.sent_time <= max_send_time) {
- pending_packets_.erase(it++);
- send_algorithm_->OnPacketAbandoned(
- sequence_number, packet_history_map_[sequence_number]->bytes_sent());
- } else {
- ++it;
- }
- }
// Attempt to send all the unacked packets when the RTO fires, let the
// congestion manager decide how many to send immediately and the remaining
@@ -516,13 +503,16 @@ void QuicSentPacketManager::OnRetransmissionTimeout() {
DVLOG(1) << "OnRetransmissionTimeout() fired with "
<< unacked_packets_.size() << " unacked packets.";
- // Retransmit any packet with retransmittable frames.
+ // Retransmit any packet with retransmittable frames and abandon the rest.
bool packets_retransmitted = false;
for (UnackedPacketMap::const_iterator it = unacked_packets_.begin();
it != unacked_packets_.end(); ++it) {
if (it->second.retransmittable_frames != NULL) {
+ OnPacketAbandoned(it->first);
packets_retransmitted = true;
MarkForRetransmission(it->first, RTO_RETRANSMISSION);
+ } else if (it->second.sent_time <= max_send_time) {
+ OnPacketAbandoned(it->first);
}
}
@@ -551,38 +541,28 @@ void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame(
frame, feedback_receive_time, packet_history_map_);
}
-SequenceNumberSet QuicSentPacketManager::OnIncomingAckFrame(
+void QuicSentPacketManager::MaybeRetransmitOnAckFrame(
const ReceivedPacketInfo& received_info,
const QuicTime& ack_receive_time) {
- MaybeUpdateRTT(received_info, ack_receive_time);
-
- // We want to.
- // * Get all packets lower(including) than largest_observed
- // from pending_packets_.
- // * Remove all packets no longer being waited for(ie: acked).
- // * Send each ACK in the list to send_algorithm_.
+ // Go through all pending packets up to the largest observed and see if any
+ // need to be retransmitted or lost.
SequenceNumberSet::iterator it = pending_packets_.begin();
SequenceNumberSet::iterator it_upper =
pending_packets_.upper_bound(received_info.largest_observed);
- SequenceNumberSet retransmission_packets;
+ size_t num_retransmitted = 0;
SequenceNumberSet lost_packets;
while (it != it_upper) {
QuicPacketSequenceNumber sequence_number = *it;
+ DVLOG(1) << "still missing packet " << sequence_number;
+ // Acks must be handled previously, so ensure it's missing and not acked.
+ DCHECK(IsAwaitingPacket(received_info, sequence_number));
+ DCHECK(ContainsKey(packet_history_map_, sequence_number));
const SendAlgorithmInterface::SentPacket* sent_packet =
packet_history_map_[sequence_number];
- if (!IsAwaitingPacket(received_info, sequence_number)) {
- // Not missing, hence implicitly acked.
- size_t bytes_sent = sent_packet->bytes_sent();
- send_algorithm_->OnPacketAcked(sequence_number, bytes_sent, rtt_sample_);
- pending_packets_.erase(it++); // Must be incremented post to work.
- continue;
- }
+ const TransmissionInfo& transmission_info =
+ unacked_packets_[sequence_number];
- // The peer got packets after this sequence number. This is an explicit
- // nack.
- DVLOG(1) << "still missing packet " << sequence_number;
- DCHECK(ContainsKey(packet_history_map_, sequence_number));
// Consider it multiple nacks when there is a gap between the missing packet
// and the largest observed, since the purpose of a nack threshold is to
// tolerate re-ordering. This handles both StretchAcks and Forward Acks.
@@ -595,8 +575,8 @@ SequenceNumberSet QuicSentPacketManager::OnIncomingAckFrame(
// Check for early retransmit(RFC5827) when the last packet gets acked and
// the there are fewer than 4 pending packets.
if (pending_packets_.size() <= kNumberOfNacksBeforeRetransmission &&
- sent_packet->has_retransmittable_data() == HAS_RETRANSMITTABLE_DATA &&
- *pending_packets_.rbegin() == received_info.largest_observed) {
+ transmission_info.retransmittable_frames &&
+ packet_history_map_.rbegin()->first == received_info.largest_observed) {
num_nacks_needed = received_info.largest_observed - sequence_number;
}
@@ -607,14 +587,15 @@ SequenceNumberSet QuicSentPacketManager::OnIncomingAckFrame(
// If the number of retransmissions has maxed out, don't lose or retransmit
// any more packets.
- if (retransmission_packets.size() >= kMaxRetransmissionsPerAck) {
+ if (num_retransmitted >= kMaxRetransmissionsPerAck) {
++it;
continue;
}
lost_packets.insert(sequence_number);
- if (sent_packet->has_retransmittable_data() == HAS_RETRANSMITTABLE_DATA) {
- retransmission_packets.insert(sequence_number);
+ if (transmission_info.retransmittable_frames) {
+ ++num_retransmitted;
+ MarkForRetransmission(*it, NACK_RETRANSMISSION);
}
++it;
@@ -632,8 +613,6 @@ SequenceNumberSet QuicSentPacketManager::OnIncomingAckFrame(
send_algorithm_->OnPacketLost(*it, ack_receive_time);
OnPacketAbandoned(*it);
}
-
- return retransmission_packets;
}
void QuicSentPacketManager::MaybeUpdateRTT(
@@ -687,6 +666,13 @@ const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() {
return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2);
}
+const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
+ if (pending_packets_.empty()) {
+ return QuicTime::Zero();
+ }
+ return clock_->ApproximateNow().Add(GetRetransmissionDelay());
+}
+
const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
size_t number_retransmissions = consecutive_rto_count_;
if (FLAGS_limit_rto_increase_for_tests) {
diff --git a/net/quic/quic_sent_packet_manager.h b/net/quic/quic_sent_packet_manager.h
index 71c61e9..70129c8 100644
--- a/net/quic/quic_sent_packet_manager.h
+++ b/net/quic/quic_sent_packet_manager.h
@@ -94,7 +94,8 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
// Discards any information for the packet corresponding to |sequence_number|.
// If this packet has been retransmitted, information on those packets
- // will be discarded as well.
+ // will be discarded as well. Also discards it from the congestion window if
+ // it is present.
void DiscardUnackedPacket(QuicPacketSequenceNumber sequence_number);
// Returns true if the non-FEC packet |sequence_number| is unacked.
@@ -133,15 +134,6 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
// Returns true if |sequence_number| is a previous transmission of packet.
bool IsPreviousTransmission(QuicPacketSequenceNumber sequence_number) const;
- // TODO(ianswett): Combine the congestion control related methods below with
- // some of the methods above and cleanup the resulting code.
- // Called when we have received an ack frame from peer.
- // Returns a set containing all the sequence numbers to be nack retransmitted
- // as a result of the ack.
- virtual SequenceNumberSet OnIncomingAckFrame(
- const ReceivedPacketInfo& received_info,
- const QuicTime& ack_receive_time);
-
// Called when a congestion feedback frame is received from peer.
virtual void OnIncomingQuicCongestionFeedbackFrame(
const QuicCongestionFeedbackFrame& frame,
@@ -175,6 +167,11 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
// Returns amount of time for delayed ack timer.
const QuicTime::Delta DelayedAckTime();
+ // Returns the current delay for the retransmission timer, which may send
+ // either a tail loss probe or do a full RTO. Retrans QuicTime::Zero() if
+ // there are no outstanding packets to abandon or retransmit.
+ const QuicTime GetRetransmissionTime() const;
+
// Returns the current RTO delay.
const QuicTime::Delta GetRetransmissionDelay() const;
@@ -200,6 +197,11 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
friend class test::QuicConnectionPeer;
friend class test::QuicSentPacketManagerPeer;
+ enum ReceivedByPeer {
+ RECEIVED_BY_PEER,
+ NOT_RECEIVED_BY_PEER,
+ };
+
struct TransmissionInfo {
TransmissionInfo()
: retransmittable_frames(NULL),
@@ -227,8 +229,6 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
TransmissionInfo> UnackedPacketMap;
typedef linked_hash_map<QuicPacketSequenceNumber,
TransmissionType> PendingRetransmissionMap;
- typedef base::hash_map<QuicPacketSequenceNumber, SequenceNumberSet*>
- PreviousTransmissionMap;
// Process the incoming ack looking for newly ack'd data packets.
void HandleAckForSentPackets(const ReceivedPacketInfo& received_info);
@@ -237,19 +237,25 @@ class NET_EXPORT_PRIVATE QuicSentPacketManager {
void MaybeUpdateRTT(const ReceivedPacketInfo& received_info,
const QuicTime& ack_receive_time);
- // Marks |sequence_number| as having been seen by the peer. Returns an
+ // Chooses whether to nack retransmit any packets based on the receipt info.
+ // All acks have been handled before this method is invoked.
+ void MaybeRetransmitOnAckFrame(const ReceivedPacketInfo& received_info,
+ const QuicTime& ack_receive_time);
+
+ // Marks |sequence_number| as being fully handled, either due to receipt
+ // by the peer, or having been discarded as indecipherable. Returns an
// iterator to the next remaining unacked packet.
- UnackedPacketMap::iterator MarkPacketReceivedByPeer(
- QuicPacketSequenceNumber sequence_number);
+ UnackedPacketMap::iterator MarkPacketHandled(
+ QuicPacketSequenceNumber sequence_number,
+ ReceivedByPeer received_by_peer);
- // Simply removes the entries, if any, from the unacked packet map
- // and the retransmission map.
+ // Removes entries from the unacked packet map.
void DiscardPacket(QuicPacketSequenceNumber sequence_number);
// Request that |sequence_number| be retransmitted after the other pending
- // retransmissions. Returns false if there are no retransmittable frames for
- // |sequence_number| and true if it will be retransmitted.
- bool MarkForRetransmission(QuicPacketSequenceNumber sequence_number,
+ // retransmissions. Does not add it to the retransmissions if it's already
+ // a pending retransmission.
+ void MarkForRetransmission(QuicPacketSequenceNumber sequence_number,
TransmissionType transmission_type);
// Returns the length of the serialized sequence number for
diff --git a/net/quic/quic_sent_packet_manager_test.cc b/net/quic/quic_sent_packet_manager_test.cc
index 168cbf3..a0b78ec 100644
--- a/net/quic/quic_sent_packet_manager_test.cc
+++ b/net/quic/quic_sent_packet_manager_test.cc
@@ -96,12 +96,19 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
&manager_, new_sequence_number));
}
- SerializedPacket CreatePacket(QuicPacketSequenceNumber sequence_number) {
+ SerializedPacket CreateDataPacket(QuicPacketSequenceNumber sequence_number) {
+ return CreatePacket(sequence_number, true);
+ }
+
+ SerializedPacket CreatePacket(QuicPacketSequenceNumber sequence_number,
+ bool retransmittable) {
packets_.push_back(QuicPacket::NewDataPacket(
NULL, 0, false, PACKET_8BYTE_GUID, false,
PACKET_6BYTE_SEQUENCE_NUMBER));
- return SerializedPacket(sequence_number, PACKET_6BYTE_SEQUENCE_NUMBER,
- packets_.back(), 0u, new RetransmittableFrames());
+ return SerializedPacket(
+ sequence_number, PACKET_6BYTE_SEQUENCE_NUMBER,
+ packets_.back(), 0u,
+ retransmittable ? new RetransmittableFrames() : NULL);
}
SerializedPacket CreateFecPacket(QuicPacketSequenceNumber sequence_number) {
@@ -115,9 +122,9 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
void SendDataPacket(QuicPacketSequenceNumber sequence_number) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, sequence_number, _, _, _))
.Times(1).WillOnce(Return(true));
- SerializedPacket packet(CreatePacket(sequence_number));
+ SerializedPacket packet(CreateDataPacket(sequence_number));
manager_.OnSerializedPacket(packet);
- manager_.OnPacketSent(sequence_number, clock_.ApproximateNow(),
+ manager_.OnPacketSent(sequence_number, clock_.Now(),
packet.packet->length(), NOT_RETRANSMISSION,
HAS_RETRANSMITTABLE_DATA);
}
@@ -148,7 +155,7 @@ class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
TEST_F(QuicSentPacketManagerTest, IsUnacked) {
VerifyUnackedPackets(NULL, 0);
- SerializedPacket serialized_packet(CreatePacket(1));
+ SerializedPacket serialized_packet(CreateDataPacket(1));
manager_.OnSerializedPacket(serialized_packet);
@@ -159,7 +166,7 @@ TEST_F(QuicSentPacketManagerTest, IsUnacked) {
}
TEST_F(QuicSentPacketManagerTest, IsUnAckedRetransmit) {
- SerializedPacket serialized_packet(CreatePacket(1));
+ SerializedPacket serialized_packet(CreateDataPacket(1));
manager_.OnSerializedPacket(serialized_packet);
RetransmitPacket(1, 2);
@@ -172,7 +179,7 @@ TEST_F(QuicSentPacketManagerTest, IsUnAckedRetransmit) {
}
TEST_F(QuicSentPacketManagerTest, RetransmitThenAck) {
- SerializedPacket serialized_packet(CreatePacket(1));
+ SerializedPacket serialized_packet(CreateDataPacket(1));
manager_.OnSerializedPacket(serialized_packet);
RetransmitPacket(1, 2);
@@ -189,7 +196,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAck) {
}
TEST_F(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) {
- SerializedPacket serialized_packet(CreatePacket(1));
+ SerializedPacket serialized_packet(CreateDataPacket(1));
manager_.OnSerializedPacket(serialized_packet);
QuicSentPacketManagerPeer::MarkForRetransmission(
@@ -210,7 +217,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) {
}
TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPrevious) {
- SerializedPacket serialized_packet(CreatePacket(1));
+ SerializedPacket serialized_packet(CreateDataPacket(1));
manager_.OnSerializedPacket(serialized_packet);
RetransmitPacket(1, 2);
@@ -234,7 +241,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPrevious) {
}
TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
- SerializedPacket serialized_packet(CreatePacket(1));
+ SerializedPacket serialized_packet(CreateDataPacket(1));
manager_.OnSerializedPacket(serialized_packet);
RetransmitPacket(1, 2);
@@ -259,7 +266,7 @@ TEST_F(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
}
TEST_F(QuicSentPacketManagerTest, TruncatedAck) {
- SerializedPacket serialized_packet(CreatePacket(1));
+ SerializedPacket serialized_packet(CreateDataPacket(1));
manager_.OnSerializedPacket(serialized_packet);
RetransmitPacket(1, 2);
@@ -282,9 +289,9 @@ TEST_F(QuicSentPacketManagerTest, TruncatedAck) {
}
TEST_F(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) {
- manager_.OnSerializedPacket(CreatePacket(1));
- manager_.OnSerializedPacket(CreatePacket(2));
- manager_.OnSerializedPacket(CreatePacket(3));
+ manager_.OnSerializedPacket(CreateDataPacket(1));
+ manager_.OnSerializedPacket(CreateDataPacket(2));
+ manager_.OnSerializedPacket(CreateDataPacket(3));
{
// Ack packets 1 and 3.
@@ -299,8 +306,8 @@ TEST_F(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) {
VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
}
- manager_.OnSerializedPacket(CreatePacket(4));
- manager_.OnSerializedPacket(CreatePacket(5));
+ manager_.OnSerializedPacket(CreateDataPacket(4));
+ manager_.OnSerializedPacket(CreateDataPacket(5));
{
// Ack packets 5.
@@ -316,8 +323,8 @@ TEST_F(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) {
VerifyRetransmittablePackets(retransmittable, arraysize(retransmittable));
}
- manager_.OnSerializedPacket(CreatePacket(6));
- manager_.OnSerializedPacket(CreatePacket(7));
+ manager_.OnSerializedPacket(CreateDataPacket(6));
+ manager_.OnSerializedPacket(CreateDataPacket(7));
{
// Ack packets 7.
@@ -335,8 +342,8 @@ TEST_F(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) {
}
RetransmitPacket(2, 8);
- manager_.OnSerializedPacket(CreatePacket(9));
- manager_.OnSerializedPacket(CreatePacket(10));
+ manager_.OnSerializedPacket(CreateDataPacket(9));
+ manager_.OnSerializedPacket(CreateDataPacket(10));
{
// Ack packet 10.
@@ -357,8 +364,8 @@ TEST_F(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) {
RetransmitPacket(4, 11);
- manager_.OnSerializedPacket(CreatePacket(12));
- manager_.OnSerializedPacket(CreatePacket(13));
+ manager_.OnSerializedPacket(CreateDataPacket(12));
+ manager_.OnSerializedPacket(CreateDataPacket(13));
{
// Ack packet 13.
@@ -380,8 +387,8 @@ TEST_F(QuicSentPacketManagerTest, SendDropAckRetransmitManyPackets) {
}
RetransmitPacket(6, 14);
- manager_.OnSerializedPacket(CreatePacket(15));
- manager_.OnSerializedPacket(CreatePacket(16));
+ manager_.OnSerializedPacket(CreateDataPacket(15));
+ manager_.OnSerializedPacket(CreateDataPacket(16));
{
// Ack packet 16.
@@ -411,7 +418,7 @@ TEST_F(QuicSentPacketManagerTest, GetLeastUnackedSentPacket) {
}
TEST_F(QuicSentPacketManagerTest, GetLeastUnackedSentPacketUnacked) {
- SerializedPacket serialized_packet(CreatePacket(1));
+ SerializedPacket serialized_packet(CreateDataPacket(1));
manager_.OnSerializedPacket(serialized_packet);
EXPECT_EQ(1u, manager_.GetLeastUnackedSentPacket());
@@ -425,7 +432,7 @@ TEST_F(QuicSentPacketManagerTest, GetLeastUnackedSentPacketUnackedFec) {
}
TEST_F(QuicSentPacketManagerTest, GetLeastUnackedSentPacketDiscardUnacked) {
- SerializedPacket serialized_packet(CreatePacket(1));
+ SerializedPacket serialized_packet(CreateDataPacket(1));
manager_.OnSerializedPacket(serialized_packet);
manager_.DiscardUnackedPacket(1u);
@@ -498,10 +505,7 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit1Packet) {
const size_t kNumSentPackets = 4;
// Transmit 4 packets.
for (size_t i = 1; i <= kNumSentPackets; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(1).WillOnce(Return(true));
- manager_.OnPacketSent(i, clock_.Now(), 1000,
- NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
+ SendDataPacket(i);
}
// Nack the first packet 3 times with increasing largest observed.
@@ -516,9 +520,10 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit1Packet) {
EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1);
EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1);
}
- SequenceNumberSet retransmissions =
- manager_.OnIncomingAckFrame(received_info, clock_.Now());
- EXPECT_EQ(i == 3 ? 1u : 0u, retransmissions.size());
+ manager_.OnIncomingAck(received_info, clock_.Now());
+ EXPECT_EQ(
+ i == 3 ? 1u : 0u,
+ QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_));
EXPECT_EQ(i, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1));
}
}
@@ -529,10 +534,7 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit1PacketWith1StretchAck) {
const size_t kNumSentPackets = 4;
// Transmit 4 packets.
for (size_t i = 1; i <= kNumSentPackets; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(1).WillOnce(Return(true));
- manager_.OnPacketSent(i, clock_.Now(), 1000,
- NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
+ SendDataPacket(i);
}
// Nack the first packet 3 times in a single StretchAck.
@@ -544,21 +546,18 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit1PacketWith1StretchAck) {
EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _, _)).Times(3);
EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1);
EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1);
- SequenceNumberSet retransmissions =
- manager_.OnIncomingAckFrame(received_info, clock_.Now());
- EXPECT_EQ(1u, retransmissions.size());
+ manager_.OnIncomingAck(received_info, clock_.Now());
+ EXPECT_EQ(
+ 1u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_));
EXPECT_EQ(3u, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1));
}
// Ack a packet 3 packets ahead, causing a retransmit.
TEST_F(QuicSentPacketManagerTest, NackRetransmit1PacketSingleAck) {
- const size_t kNumSentPackets = 4;
- // Transmit 4 packets.
+ const size_t kNumSentPackets = 5;
+ // Transmit 5 packets.
for (size_t i = 1; i <= kNumSentPackets; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(1).WillOnce(Return(true));
- manager_.OnPacketSent(i, clock_.Now(), 1000,
- NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
+ SendDataPacket(i);
}
// Nack the first packet 3 times in an AckFrame with three missing packets.
@@ -568,13 +567,13 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit1PacketSingleAck) {
received_info.missing_packets.insert(1);
received_info.missing_packets.insert(2);
received_info.missing_packets.insert(3);
- received_info.largest_observed = kNumSentPackets;
- EXPECT_CALL(*send_algorithm_, OnPacketAcked(kNumSentPackets, _, _)).Times(1);
+ received_info.largest_observed = 4;
+ EXPECT_CALL(*send_algorithm_, OnPacketAcked(4, _, _)).Times(1);
EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1);
EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1);
- SequenceNumberSet retransmissions =
- manager_.OnIncomingAckFrame(received_info, clock_.Now());
- EXPECT_EQ(1u, retransmissions.size());
+ manager_.OnIncomingAck(received_info, clock_.Now());
+ EXPECT_EQ(
+ 1u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_));
EXPECT_EQ(3u, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1));
}
@@ -582,10 +581,7 @@ TEST_F(QuicSentPacketManagerTest, EarlyRetransmit1Packet) {
const size_t kNumSentPackets = 2;
// Transmit 2 packets.
for (size_t i = 1; i <= kNumSentPackets; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(1).WillOnce(Return(true));
- manager_.OnPacketSent(i, clock_.Now(), 1000,
- NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
+ SendDataPacket(i);
}
// Early retransmit when the final packet gets acked and the first is nacked.
@@ -597,19 +593,16 @@ TEST_F(QuicSentPacketManagerTest, EarlyRetransmit1Packet) {
EXPECT_CALL(*send_algorithm_, OnPacketAcked(kNumSentPackets, _, _)).Times(1);
EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1);
EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1);
- SequenceNumberSet retransmissions =
- manager_.OnIncomingAckFrame(received_info, clock_.Now());
- EXPECT_EQ(1u, retransmissions.size());
+ manager_.OnIncomingAck(received_info, clock_.Now());
+ EXPECT_EQ(
+ 1u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_));
EXPECT_EQ(1u, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1));
}
TEST_F(QuicSentPacketManagerTest, DontEarlyRetransmitPacket) {
- const size_t kNumSentPackets = 4;
+ const size_t kNumSentPackets = 5;
for (size_t i = 1; i <= kNumSentPackets; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(1).WillOnce(Return(true));
- manager_.OnPacketSent(i, clock_.Now(), 1000,
- NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
+ SendDataPacket(i);
}
// Fast retransmit when the final packet gets acked, but don't early
@@ -621,24 +614,22 @@ TEST_F(QuicSentPacketManagerTest, DontEarlyRetransmitPacket) {
received_info.missing_packets.insert(1);
received_info.missing_packets.insert(2);
received_info.missing_packets.insert(3);
+ received_info.missing_packets.insert(4);
received_info.largest_observed = kNumSentPackets;
- EXPECT_CALL(*send_algorithm_, OnPacketAcked(kNumSentPackets, _, _)).Times(1);
- EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1);
- EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1);
- SequenceNumberSet retransmissions =
- manager_.OnIncomingAckFrame(received_info, clock_.Now());
- EXPECT_EQ(1u, retransmissions.size());
- EXPECT_EQ(3u, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1));
+ EXPECT_CALL(*send_algorithm_, OnPacketAcked(5, _, _)).Times(1);
+ EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2);
+ EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2);
+ manager_.OnIncomingAck(received_info, clock_.Now());
+ EXPECT_EQ(
+ 2u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_));
+ EXPECT_EQ(4u, QuicSentPacketManagerPeer::GetNackCount(&manager_, 1));
}
TEST_F(QuicSentPacketManagerTest, NackRetransmit2Packets) {
const size_t kNumSentPackets = 20;
// Transmit 20 packets.
for (QuicPacketSequenceNumber i = 1; i <= kNumSentPackets; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(1).WillOnce(Return(true));
- manager_.OnPacketSent(i, clock_.Now(), 1000,
- NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
+ SendDataPacket(i);
}
// Nack the first 19 packets 3 times.
@@ -653,9 +644,9 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit2Packets) {
OnPacketAcked(kNumSentPackets, _, _)).Times(1);
EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2);
EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2);
- SequenceNumberSet retransmissions =
- manager_.OnIncomingAckFrame(received_info, clock_.Now());
- EXPECT_EQ(2u, retransmissions.size());
+ manager_.OnIncomingAck(received_info, clock_.Now());
+ EXPECT_EQ(
+ 2u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_));
for (size_t i = 1; i < kNumSentPackets; ++i) {
EXPECT_EQ(kNumSentPackets - i,
QuicSentPacketManagerPeer::GetNackCount(&manager_, i));
@@ -669,6 +660,8 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit2PacketsAlternateAcks) {
for (QuicPacketSequenceNumber i = 1; i <= kNumSentPackets; ++i) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
.Times(1).WillOnce(Return(i % 2 == 0 ? false : true));
+ SerializedPacket packet(CreatePacket(i, i % 2 == 1));
+ manager_.OnSerializedPacket(packet);
manager_.OnPacketSent(
i, clock_.Now(), 1000, NOT_RETRANSMISSION,
i % 2 == 0 ? NO_RETRANSMITTABLE_DATA : HAS_RETRANSMITTABLE_DATA);
@@ -686,9 +679,9 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit2PacketsAlternateAcks) {
// not saved.
EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2);
EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2);
- SequenceNumberSet retransmissions =
- manager_.OnIncomingAckFrame(received_info, clock_.Now());
- EXPECT_EQ(2u, retransmissions.size());
+ manager_.OnIncomingAck(received_info, clock_.Now());
+ ASSERT_EQ(
+ 2u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_));
// Only non-ack packets have a nack count.
for (size_t i = 1; i < kNumSentPackets; i += 2) {
EXPECT_EQ(kNumSentPackets - i,
@@ -697,19 +690,15 @@ TEST_F(QuicSentPacketManagerTest, NackRetransmit2PacketsAlternateAcks) {
// Ensure only the odd packets were retransmitted, since the others were not
// retransmittable(ie: acks).
- for (SequenceNumberSet::const_iterator it = retransmissions.begin();
- it != retransmissions.end(); ++it) {
- EXPECT_EQ(1u, *it % 2);
- }
+ EXPECT_EQ(1u, manager_.NextPendingRetransmission().sequence_number);
+ manager_.OnRetransmittedPacket(1u, kNumSentPackets + 1);
+ EXPECT_EQ(3u, manager_.NextPendingRetransmission().sequence_number);
}
TEST_F(QuicSentPacketManagerTest, NackTwiceThenAck) {
// Transmit 4 packets.
for (QuicPacketSequenceNumber i = 1; i <= 4; ++i) {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(1).WillOnce(Return(true));
- manager_.OnPacketSent(i, clock_.Now(), 1000,
- NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
+ SendDataPacket(i);
}
// Nack the first packet 2 times, then ack it.
@@ -724,9 +713,8 @@ TEST_F(QuicSentPacketManagerTest, NackTwiceThenAck) {
QuicTime::Delta::FromMilliseconds(5);
EXPECT_CALL(*send_algorithm_,
OnPacketAcked(_, _, _)).Times(i == 3 ? 2 : 1);
- SequenceNumberSet retransmissions =
- manager_.OnIncomingAckFrame(received_info, clock_.Now());
- EXPECT_EQ(0u, retransmissions.size());
+ manager_.OnIncomingAck(received_info, clock_.Now());
+ EXPECT_FALSE(manager_.HasPendingRetransmissions());
// The nack count remains at 2 when the packet is acked.
EXPECT_EQ(i == 3 ? 2u : i,
QuicSentPacketManagerPeer::GetNackCount(&manager_, 1));
@@ -736,21 +724,16 @@ TEST_F(QuicSentPacketManagerTest, NackTwiceThenAck) {
TEST_F(QuicSentPacketManagerTest, Rtt) {
QuicPacketSequenceNumber sequence_number = 1;
QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(15);
+ SendDataPacket(sequence_number);
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(1).WillOnce(Return(true));
EXPECT_CALL(*send_algorithm_,
OnPacketAcked(sequence_number, _, expected_rtt)).Times(1);
-
- manager_.OnPacketSent(sequence_number, clock_.Now(), 1000,
- NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
-
ReceivedPacketInfo received_info;
received_info.largest_observed = sequence_number;
received_info.delta_time_largest_observed =
QuicTime::Delta::FromMilliseconds(5);
- manager_.OnIncomingAckFrame(received_info, clock_.Now());
+ manager_.OnIncomingAck(received_info, clock_.Now());
EXPECT_EQ(expected_rtt, QuicSentPacketManagerPeer::rtt(&manager_));
}
@@ -760,21 +743,16 @@ TEST_F(QuicSentPacketManagerTest, RttWithInvalidDelta) {
// and is hence invalid.
QuicPacketSequenceNumber sequence_number = 1;
QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
+ SendDataPacket(sequence_number);
+ clock_.AdvanceTime(expected_rtt);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(1).WillOnce(Return(true));
EXPECT_CALL(*send_algorithm_,
- OnPacketAcked(sequence_number, _, expected_rtt)).Times(1);
-
- manager_.OnPacketSent(sequence_number, clock_.Now(), 1000,
- NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-
+ OnPacketAcked(sequence_number, _, expected_rtt)).Times(1);
ReceivedPacketInfo received_info;
received_info.largest_observed = sequence_number;
received_info.delta_time_largest_observed =
QuicTime::Delta::FromMilliseconds(11);
- manager_.OnIncomingAckFrame(received_info, clock_.Now());
+ manager_.OnIncomingAck(received_info, clock_.Now());
EXPECT_EQ(expected_rtt, QuicSentPacketManagerPeer::rtt(&manager_));
}
@@ -783,20 +761,15 @@ TEST_F(QuicSentPacketManagerTest, RttWithInfiniteDelta) {
// delta_time_largest_observed is infinite, and is hence invalid.
QuicPacketSequenceNumber sequence_number = 1;
QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
+ SendDataPacket(sequence_number);
+ clock_.AdvanceTime(expected_rtt);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(1).WillOnce(Return(true));
EXPECT_CALL(*send_algorithm_,
OnPacketAcked(sequence_number, _, expected_rtt)).Times(1);
-
- manager_.OnPacketSent(sequence_number, clock_.Now(), 1000,
- NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
- clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-
ReceivedPacketInfo received_info;
received_info.largest_observed = sequence_number;
received_info.delta_time_largest_observed = QuicTime::Delta::Infinite();
- manager_.OnIncomingAckFrame(received_info, clock_.Now());
+ manager_.OnIncomingAck(received_info, clock_.Now());
EXPECT_EQ(expected_rtt, QuicSentPacketManagerPeer::rtt(&manager_));
}
@@ -805,20 +778,15 @@ TEST_F(QuicSentPacketManagerTest, RttZeroDelta) {
// delta_time_largest_observed is zero.
QuicPacketSequenceNumber sequence_number = 1;
QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
+ SendDataPacket(sequence_number);
+ clock_.AdvanceTime(expected_rtt);
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
- .Times(1).WillOnce(Return(true));
EXPECT_CALL(*send_algorithm_, OnPacketAcked(sequence_number, _, expected_rtt))
.Times(1);
-
- manager_.OnPacketSent(sequence_number, clock_.Now(), 1000,
- NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
- clock_.AdvanceTime(expected_rtt);
-
ReceivedPacketInfo received_info;
received_info.largest_observed = sequence_number;
received_info.delta_time_largest_observed = QuicTime::Delta::Zero();
- manager_.OnIncomingAckFrame(received_info, clock_.Now());
+ manager_.OnIncomingAck(received_info, clock_.Now());
EXPECT_EQ(expected_rtt, QuicSentPacketManagerPeer::rtt(&manager_));
}
@@ -837,6 +805,10 @@ TEST_F(QuicSentPacketManagerTest, RetransmissionTimeout) {
manager_.OnRetransmissionTimeout();
}
+TEST_F(QuicSentPacketManagerTest, GetTransmissionTime) {
+ EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayMin) {
EXPECT_CALL(*send_algorithm_, RetransmissionDelay())
.WillOnce(Return(QuicTime::Delta::FromMilliseconds(1)));
diff --git a/net/quic/test_tools/quic_sent_packet_manager_peer.cc b/net/quic/test_tools/quic_sent_packet_manager_peer.cc
index e2e7c02..429a405 100644
--- a/net/quic/test_tools/quic_sent_packet_manager_peer.cc
+++ b/net/quic/test_tools/quic_sent_packet_manager_peer.cc
@@ -28,6 +28,12 @@ size_t QuicSentPacketManagerPeer::GetNackCount(
}
// static
+size_t QuicSentPacketManagerPeer::GetPendingRetransmissionCount(
+ const QuicSentPacketManager* sent_packet_manager) {
+ return sent_packet_manager->pending_retransmissions_.size();
+}
+
+// static
QuicTime QuicSentPacketManagerPeer::GetSentTime(
const QuicSentPacketManager* sent_packet_manager,
QuicPacketSequenceNumber sequence_number) {
diff --git a/net/quic/test_tools/quic_sent_packet_manager_peer.h b/net/quic/test_tools/quic_sent_packet_manager_peer.h
index 2ed9b21..9728d43 100644
--- a/net/quic/test_tools/quic_sent_packet_manager_peer.h
+++ b/net/quic/test_tools/quic_sent_packet_manager_peer.h
@@ -23,6 +23,9 @@ class QuicSentPacketManagerPeer {
const QuicSentPacketManager* sent_packet_manager,
QuicPacketSequenceNumber sequence_number);
+ static size_t GetPendingRetransmissionCount(
+ const QuicSentPacketManager* sent_packet_manager);
+
static QuicTime GetSentTime(const QuicSentPacketManager* sent_packet_manager,
QuicPacketSequenceNumber sequence_number);
diff --git a/net/quic/test_tools/quic_session_peer.cc b/net/quic/test_tools/quic_session_peer.cc
index c25b42f..c1fe7e0 100644
--- a/net/quic/test_tools/quic_session_peer.cc
+++ b/net/quic/test_tools/quic_session_peer.cc
@@ -27,5 +27,12 @@ WriteBlockedList<QuicStreamId>* QuicSessionPeer::GetWriteblockedStreams(
return &session->write_blocked_streams_;
}
+// static
+QuicDataStream* QuicSessionPeer::GetIncomingReliableStream(
+ QuicSession* session,
+ QuicStreamId stream_id) {
+ return session->GetIncomingReliableStream(stream_id);
+}
+
} // namespace test
} // namespace net
diff --git a/net/quic/test_tools/quic_session_peer.h b/net/quic/test_tools/quic_session_peer.h
index fb4529c..3151d84 100644
--- a/net/quic/test_tools/quic_session_peer.h
+++ b/net/quic/test_tools/quic_session_peer.h
@@ -10,6 +10,7 @@
namespace net {
+class QuicDataStream;
class QuicSession;
class ReliableQuicStream;
@@ -21,6 +22,8 @@ class QuicSessionPeer {
static void SetMaxOpenStreams(QuicSession* session, uint32 max_streams);
static WriteBlockedList<QuicStreamId>* GetWriteblockedStreams(
QuicSession* session);
+ static QuicDataStream* GetIncomingReliableStream(QuicSession* session,
+ QuicStreamId stream_id);
private:
DISALLOW_COPY_AND_ASSIGN(QuicSessionPeer);
diff --git a/net/quic/test_tools/reliable_quic_stream_peer.cc b/net/quic/test_tools/reliable_quic_stream_peer.cc
index 5119d03..6379c07 100644
--- a/net/quic/test_tools/reliable_quic_stream_peer.cc
+++ b/net/quic/test_tools/reliable_quic_stream_peer.cc
@@ -22,5 +22,10 @@ void ReliableQuicStreamPeer::SetStreamBytesWritten(
stream->stream_bytes_written_ = stream_bytes_written;
}
+// static
+void ReliableQuicStreamPeer::CloseReadSide(ReliableQuicStream* stream) {
+ stream->CloseReadSide();
+}
+
} // namespace test
} // namespace net
diff --git a/net/quic/test_tools/reliable_quic_stream_peer.h b/net/quic/test_tools/reliable_quic_stream_peer.h
index da229da..291794f 100644
--- a/net/quic/test_tools/reliable_quic_stream_peer.h
+++ b/net/quic/test_tools/reliable_quic_stream_peer.h
@@ -19,6 +19,7 @@ class ReliableQuicStreamPeer {
static void SetWriteSideClosed(bool value, ReliableQuicStream* stream);
static void SetStreamBytesWritten(QuicStreamOffset stream_bytes_written,
ReliableQuicStream* stream);
+ static void CloseReadSide(ReliableQuicStream* stream);
private:
DISALLOW_COPY_AND_ASSIGN(ReliableQuicStreamPeer);
diff --git a/net/tools/quic/quic_server_session.h b/net/tools/quic/quic_server_session.h
index f470551..ff921bb 100644
--- a/net/tools/quic/quic_server_session.h
+++ b/net/tools/quic/quic_server_session.h
@@ -52,7 +52,9 @@ class QuicServerSession : public QuicSession {
virtual void InitializeSession(const QuicCryptoServerConfig& crypto_config);
- const QuicCryptoServerStream* crypto_stream() { return crypto_stream_.get(); }
+ const QuicCryptoServerStream* crypto_stream() const {
+ return crypto_stream_.get();
+ }
protected:
// QuicSession methods: