summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/quic/congestion_control/fix_rate_receiver.cc7
-rw-r--r--net/quic/congestion_control/fix_rate_receiver.h3
-rw-r--r--net/quic/congestion_control/fix_rate_sender.cc12
-rw-r--r--net/quic/congestion_control/fix_rate_sender.h4
-rw-r--r--net/quic/congestion_control/fix_rate_test.cc22
-rw-r--r--net/quic/congestion_control/quic_receipt_metrics_collector.cc6
-rw-r--r--net/quic/congestion_control/quic_receipt_metrics_collector.h13
-rw-r--r--net/quic/congestion_control/quic_receipt_metrics_collector_test.cc6
-rw-r--r--net/quic/congestion_control/quic_send_scheduler.cc9
-rw-r--r--net/quic/congestion_control/quic_send_scheduler.h4
-rw-r--r--net/quic/congestion_control/quic_send_scheduler_test.cc50
-rw-r--r--net/quic/congestion_control/receive_algorithm_interface.cc3
-rw-r--r--net/quic/congestion_control/receive_algorithm_interface.h7
-rw-r--r--net/quic/congestion_control/send_algorithm_interface.cc3
-rw-r--r--net/quic/congestion_control/send_algorithm_interface.h6
-rw-r--r--net/quic/congestion_control/tcp_cubic_sender.cc12
-rw-r--r--net/quic/congestion_control/tcp_cubic_sender.h4
-rw-r--r--net/quic/congestion_control/tcp_cubic_sender_test.cc32
-rw-r--r--net/quic/congestion_control/tcp_receiver.cc9
-rw-r--r--net/quic/congestion_control/tcp_receiver.h4
-rw-r--r--net/quic/congestion_control/tcp_receiver_test.cc18
-rw-r--r--net/quic/quic_connection.cc20
-rw-r--r--net/quic/quic_connection.h3
-rw-r--r--net/quic/quic_connection_helper_test.cc38
-rw-r--r--net/quic/quic_connection_test.cc162
-rw-r--r--net/quic/quic_framer.cc76
-rw-r--r--net/quic/quic_framer.h10
-rw-r--r--net/quic/quic_framer_test.cc630
-rw-r--r--net/quic/quic_http_stream_test.cc63
-rw-r--r--net/quic/quic_packet_creator.cc13
-rw-r--r--net/quic/quic_packet_creator.h2
-rw-r--r--net/quic/quic_protocol.cc10
-rw-r--r--net/quic/quic_protocol.h52
-rw-r--r--net/quic/quic_stream_factory_test.cc33
-rw-r--r--net/quic/test_tools/quic_test_utils.cc10
-rw-r--r--net/quic/test_tools/quic_test_utils.h14
36 files changed, 601 insertions, 769 deletions
diff --git a/net/quic/congestion_control/fix_rate_receiver.cc b/net/quic/congestion_control/fix_rate_receiver.cc
index 692765e..b2b5f8e 100644
--- a/net/quic/congestion_control/fix_rate_receiver.cc
+++ b/net/quic/congestion_control/fix_rate_receiver.cc
@@ -17,9 +17,10 @@ FixRateReceiver::FixRateReceiver()
: bitrate_in_bytes_per_second_(kInitialBitrate) {
}
-bool FixRateReceiver::GenerateCongestionInfo(CongestionInfo* congestion_info) {
- congestion_info->type = kFixRate;
- congestion_info->fix_rate.bitrate_in_bytes_per_second =
+bool FixRateReceiver::GenerateCongestionFeedback(
+ QuicCongestionFeedbackFrame* feedback) {
+ feedback->type = kFixRate;
+ feedback->fix_rate.bitrate_in_bytes_per_second =
bitrate_in_bytes_per_second_;
return true;
}
diff --git a/net/quic/congestion_control/fix_rate_receiver.h b/net/quic/congestion_control/fix_rate_receiver.h
index 54c6df9..d550f13 100644
--- a/net/quic/congestion_control/fix_rate_receiver.h
+++ b/net/quic/congestion_control/fix_rate_receiver.h
@@ -19,7 +19,8 @@ class NET_EXPORT_PRIVATE FixRateReceiver : public ReceiveAlgorithmInterface {
FixRateReceiver();
// Implements ReceiveAlgorithmInterface.
- virtual bool GenerateCongestionInfo(CongestionInfo* congestion_info) OVERRIDE;
+ virtual bool GenerateCongestionFeedback(
+ QuicCongestionFeedbackFrame* feedback) OVERRIDE;
// Implements ReceiveAlgorithmInterface.
virtual void RecordIncomingPacket(size_t bytes,
diff --git a/net/quic/congestion_control/fix_rate_sender.cc b/net/quic/congestion_control/fix_rate_sender.cc
index 3161b89..fc9b6c7 100644
--- a/net/quic/congestion_control/fix_rate_sender.cc
+++ b/net/quic/congestion_control/fix_rate_sender.cc
@@ -25,13 +25,13 @@ FixRateSender::FixRateSender(const QuicClock* clock)
DLOG(INFO) << "FixRateSender";
}
-void FixRateSender::OnIncomingCongestionInfo(
- const CongestionInfo& congestion_info) {
- DCHECK(congestion_info.type == kFixRate) <<
- "Invalid incoming CongestionFeedbackType:" << congestion_info.type;
- if (congestion_info.type == kFixRate) {
+void FixRateSender::OnIncomingQuicCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& feedback) {
+ DCHECK(feedback.type == kFixRate) <<
+ "Invalid incoming CongestionFeedbackType:" << feedback.type;
+ if (feedback.type == kFixRate) {
bitrate_in_bytes_per_s_ =
- congestion_info.fix_rate.bitrate_in_bytes_per_second;
+ feedback.fix_rate.bitrate_in_bytes_per_second;
fix_rate_leaky_bucket_.SetDrainingRate(bitrate_in_bytes_per_s_);
paced_sender_.UpdateBandwidthEstimate(bitrate_in_bytes_per_s_);
}
diff --git a/net/quic/congestion_control/fix_rate_sender.h b/net/quic/congestion_control/fix_rate_sender.h
index c2d9f14..c81581c 100644
--- a/net/quic/congestion_control/fix_rate_sender.h
+++ b/net/quic/congestion_control/fix_rate_sender.h
@@ -23,8 +23,8 @@ class NET_EXPORT_PRIVATE FixRateSender : public SendAlgorithmInterface {
explicit FixRateSender(const QuicClock* clock);
// Start implementation of SendAlgorithmInterface.
- virtual void OnIncomingCongestionInfo(
- const CongestionInfo& congestion_info) OVERRIDE;
+ virtual void OnIncomingQuicCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& feedback) OVERRIDE;
virtual void OnIncomingAck(QuicPacketSequenceNumber acked_sequence_number,
size_t acked_bytes,
QuicTime::Delta rtt) OVERRIDE;
diff --git a/net/quic/congestion_control/fix_rate_test.cc b/net/quic/congestion_control/fix_rate_test.cc
index 07cfb0e..2170b5b 100644
--- a/net/quic/congestion_control/fix_rate_test.cc
+++ b/net/quic/congestion_control/fix_rate_test.cc
@@ -33,20 +33,20 @@ class FixRateTest : public ::testing::Test {
};
TEST_F(FixRateTest, ReceiverAPI) {
- CongestionInfo info;
+ QuicCongestionFeedbackFrame feedback;
QuicTime timestamp;
receiver_->SetBitrate(300000); // Bytes per second.
receiver_->RecordIncomingPacket(1, 1, timestamp, false);
- ASSERT_TRUE(receiver_->GenerateCongestionInfo(&info));
- EXPECT_EQ(kFixRate, info.type);
- EXPECT_EQ(300000u, info.fix_rate.bitrate_in_bytes_per_second);
+ ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
+ EXPECT_EQ(kFixRate, feedback.type);
+ EXPECT_EQ(300000u, feedback.fix_rate.bitrate_in_bytes_per_second);
}
TEST_F(FixRateTest, SenderAPI) {
- CongestionInfo info;
- info.type = kFixRate;
- info.fix_rate.bitrate_in_bytes_per_second = 300000;
- sender_->OnIncomingCongestionInfo(info);
+ QuicCongestionFeedbackFrame feedback;
+ feedback.type = kFixRate;
+ feedback.fix_rate.bitrate_in_bytes_per_second = 300000;
+ sender_->OnIncomingQuicCongestionFeedbackFrame(feedback);
EXPECT_EQ(300000, sender_->BandwidthEstimate());
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
EXPECT_EQ(kMaxPacketSize * 2, sender_->AvailableCongestionWindow());
@@ -71,10 +71,10 @@ TEST_F(FixRateTest, FixRatePacing) {
const int64 packet_size = 1200;
const int64 bit_rate = 240000;
const int64 num_packets = 200;
- CongestionInfo info;
+ QuicCongestionFeedbackFrame feedback;
receiver_->SetBitrate(240000); // Bytes per second.
- ASSERT_TRUE(receiver_->GenerateCongestionInfo(&info));
- sender_->OnIncomingCongestionInfo(info);
+ ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
+ sender_->OnIncomingQuicCongestionFeedbackFrame(feedback);
QuicTime acc_advance_time;
QuicPacketSequenceNumber sequence_number = 0;
for (int i = 0; i < num_packets; i += 2) {
diff --git a/net/quic/congestion_control/quic_receipt_metrics_collector.cc b/net/quic/congestion_control/quic_receipt_metrics_collector.cc
index db97750..7f3c076 100644
--- a/net/quic/congestion_control/quic_receipt_metrics_collector.cc
+++ b/net/quic/congestion_control/quic_receipt_metrics_collector.cc
@@ -17,9 +17,9 @@ QuicReceiptMetricsCollector::QuicReceiptMetricsCollector(
QuicReceiptMetricsCollector::~QuicReceiptMetricsCollector() {
}
-bool QuicReceiptMetricsCollector::GenerateCongestionInfo(
- CongestionInfo* info) {
- return receive_algorithm_->GenerateCongestionInfo(info);
+bool QuicReceiptMetricsCollector::GenerateCongestionFeedback(
+ QuicCongestionFeedbackFrame* feedback) {
+ return receive_algorithm_->GenerateCongestionFeedback(feedback);
}
void QuicReceiptMetricsCollector::RecordIncomingPacket(
diff --git a/net/quic/congestion_control/quic_receipt_metrics_collector.h b/net/quic/congestion_control/quic_receipt_metrics_collector.h
index b627067..dbd3c3c 100644
--- a/net/quic/congestion_control/quic_receipt_metrics_collector.h
+++ b/net/quic/congestion_control/quic_receipt_metrics_collector.h
@@ -3,8 +3,8 @@
// found in the LICENSE file.
//
// This is the base class for QUIC receive side congestion control.
-// This class will provide the CongestionInfo objects to outgoing ACKs if
-// needed.
+// This class will provide the QuicCongestionFeedbackFrame objects for outgoing
+// packets if needed.
// The acctual receive side algorithm is implemented via the
// ReceiveAlgorithmInterface.
@@ -28,10 +28,11 @@ class NET_EXPORT_PRIVATE QuicReceiptMetricsCollector {
virtual ~QuicReceiptMetricsCollector();
// Should be called for each ACK packet to decide if we need to attach a
- // CongestionInfo block.
- // Returns false if no CongestionInfo block is needed otherwise fills in
- // congestion_info and return true.
- virtual bool GenerateCongestionInfo(CongestionInfo* congestion_info);
+ // QuicCongestionFeedbackFrame block.
+ // Returns false if no QuicCongestionFeedbackFrame block is needed.
+ // Otherwise fills in feedback and return true.
+ virtual bool GenerateCongestionFeedback(
+ QuicCongestionFeedbackFrame* feedback);
// Should be called for each incoming packet.
// bytes: is the packet size in bytes including IP headers.
diff --git a/net/quic/congestion_control/quic_receipt_metrics_collector_test.cc b/net/quic/congestion_control/quic_receipt_metrics_collector_test.cc
index 06fa05e..7a9c4ee 100644
--- a/net/quic/congestion_control/quic_receipt_metrics_collector_test.cc
+++ b/net/quic/congestion_control/quic_receipt_metrics_collector_test.cc
@@ -22,11 +22,11 @@ class QuicReceiptMetricsCollectorTest : public ::testing::Test {
TEST_F(QuicReceiptMetricsCollectorTest, FixedRateReceiverAPI) {
SetUpCongestionType(kFixRate);
- CongestionInfo info;
+ QuicCongestionFeedbackFrame feedback;
QuicTime timestamp;
receiver_->RecordIncomingPacket(1, 1, timestamp, false);
- ASSERT_TRUE(receiver_->GenerateCongestionInfo(&info));
- EXPECT_EQ(kFixRate, info.type);
+ ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
+ EXPECT_EQ(kFixRate, feedback.type);
}
} // namespace net
diff --git a/net/quic/congestion_control/quic_send_scheduler.cc b/net/quic/congestion_control/quic_send_scheduler.cc
index c362172..17c4a2f 100644
--- a/net/quic/congestion_control/quic_send_scheduler.cc
+++ b/net/quic/congestion_control/quic_send_scheduler.cc
@@ -78,10 +78,13 @@ void QuicSendScheduler::SentPacket(QuicPacketSequenceNumber sequence_number,
DLOG(INFO) << "Sent sequence number:" << sequence_number;
}
-void QuicSendScheduler::OnIncomingAckFrame(const QuicAckFrame& ack_frame) {
- if (ack_frame.congestion_info.type != kNone) {
- send_algorithm_->OnIncomingCongestionInfo(ack_frame.congestion_info);
+void QuicSendScheduler::OnIncomingQuicCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& congestion_feedback_frame) {
+ send_algorithm_->OnIncomingQuicCongestionFeedbackFrame(
+ congestion_feedback_frame);
}
+
+void QuicSendScheduler::OnIncomingAckFrame(const QuicAckFrame& ack_frame) {
// We want to.
// * Get all packets lower(including) than largest_received
// from pending_packets_.
diff --git a/net/quic/congestion_control/quic_send_scheduler.h b/net/quic/congestion_control/quic_send_scheduler.h
index 3733007..66324ae 100644
--- a/net/quic/congestion_control/quic_send_scheduler.h
+++ b/net/quic/congestion_control/quic_send_scheduler.h
@@ -57,6 +57,10 @@ class NET_EXPORT_PRIVATE QuicSendScheduler {
// Called when we have received an ack frame from remote peer.
virtual void OnIncomingAckFrame(const QuicAckFrame& ack_frame);
+ // Called when we have received an congestion feedback frame from remote peer.
+ virtual void OnIncomingQuicCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& congestion_feedback_frame);
+
// Inform that we sent x bytest to the wire, and if that was a retransmission.
// Note: this function must be called for every packet sent to the wire.
virtual void SentPacket(QuicPacketSequenceNumber sequence_number,
diff --git a/net/quic/congestion_control/quic_send_scheduler_test.cc b/net/quic/congestion_control/quic_send_scheduler_test.cc
index 9cdd8fe..2183243 100644
--- a/net/quic/congestion_control/quic_send_scheduler_test.cc
+++ b/net/quic/congestion_control/quic_send_scheduler_test.cc
@@ -25,10 +25,10 @@ class QuicSendSchedulerTest : public ::testing::Test {
TEST_F(QuicSendSchedulerTest, FixedRateSenderAPI) {
SetUpCongestionType(kFixRate);
- QuicAckFrame ack;
- ack.congestion_info.type = kFixRate;
- ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 30000;
- sender_->OnIncomingAckFrame(ack);
+ QuicCongestionFeedbackFrame congestion_feedback;
+ congestion_feedback.type = kFixRate;
+ congestion_feedback.fix_rate.bitrate_in_bytes_per_second = 30000;
+ sender_->OnIncomingQuicCongestionFeedbackFrame(congestion_feedback);
EXPECT_EQ(-1, sender_->PeakSustainedBandwidth());
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow());
@@ -46,10 +46,14 @@ TEST_F(QuicSendSchedulerTest, FixedRateSenderAPI) {
TEST_F(QuicSendSchedulerTest, FixedRatePacing) {
SetUpCongestionType(kFixRate);
QuicAckFrame ack;
- ack.congestion_info.type = kFixRate;
- ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 100000;
ack.received_info.largest_received = 0;
sender_->OnIncomingAckFrame(ack);
+
+ QuicCongestionFeedbackFrame feedback;
+ feedback.type = kFixRate;
+ feedback.fix_rate.bitrate_in_bytes_per_second = 100000;
+ sender_->OnIncomingQuicCongestionFeedbackFrame(feedback);
+
QuicTime acc_advance_time;
for (int i = 1; i <= 100; ++i) {
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
@@ -68,9 +72,13 @@ TEST_F(QuicSendSchedulerTest, FixedRatePacing) {
TEST_F(QuicSendSchedulerTest, AvailableCongestionWindow) {
SetUpCongestionType(kFixRate);
QuicAckFrame ack;
- ack.congestion_info.type = kFixRate;
- ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 100000;
sender_->OnIncomingAckFrame(ack);
+
+ QuicCongestionFeedbackFrame feedback;
+ feedback.type = kFixRate;
+ feedback.fix_rate.bitrate_in_bytes_per_second = 100000;
+ sender_->OnIncomingQuicCongestionFeedbackFrame(feedback);
+
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
EXPECT_EQ(kMaxPacketSize, sender_->AvailableCongestionWindow());
const int32 num_packets = 12;
@@ -90,9 +98,13 @@ TEST_F(QuicSendSchedulerTest, AvailableCongestionWindow) {
TEST_F(QuicSendSchedulerTest, FixedRateBandwidth) {
SetUpCongestionType(kFixRate);
QuicAckFrame ack;
- ack.congestion_info.type = kFixRate;
- ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 100000;
sender_->OnIncomingAckFrame(ack);
+
+ QuicCongestionFeedbackFrame feedback;
+ feedback.type = kFixRate;
+ feedback.fix_rate.bitrate_in_bytes_per_second = 100000;
+ sender_->OnIncomingQuicCongestionFeedbackFrame(feedback);
+
for (int i = 1; i <= 100; ++i) {
QuicTime::Delta advance_time = sender_->TimeUntilSend(false);
clock_.AdvanceTime(advance_time);
@@ -111,9 +123,13 @@ TEST_F(QuicSendSchedulerTest, FixedRateBandwidth) {
TEST_F(QuicSendSchedulerTest, BandwidthWith3SecondGap) {
SetUpCongestionType(kFixRate);
QuicAckFrame ack;
- ack.congestion_info.type = kFixRate;
- ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 100000;
sender_->OnIncomingAckFrame(ack);
+
+ QuicCongestionFeedbackFrame feedback;
+ feedback.type = kFixRate;
+ feedback.fix_rate.bitrate_in_bytes_per_second = 100000;
+ sender_->OnIncomingQuicCongestionFeedbackFrame(feedback);
+
for (int i = 1; i <= 100; ++i) {
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
@@ -149,11 +165,15 @@ TEST_F(QuicSendSchedulerTest, BandwidthWith3SecondGap) {
TEST_F(QuicSendSchedulerTest, Pacing) {
SetUpCongestionType(kFixRate);
QuicAckFrame ack;
- ack.congestion_info.type = kFixRate;
- // Test a high bitrate (8Mbit/s) to trigger pacing.
- ack.congestion_info.fix_rate.bitrate_in_bytes_per_second = 1000000;
ack.received_info.largest_received = 0;
sender_->OnIncomingAckFrame(ack);
+
+ QuicCongestionFeedbackFrame feedback;
+ feedback.type = kFixRate;
+ // Test a high bitrate (8Mbit/s) to trigger pacing.
+ feedback.fix_rate.bitrate_in_bytes_per_second = 1000000;
+ sender_->OnIncomingQuicCongestionFeedbackFrame(feedback);
+
QuicTime acc_advance_time;
for (int i = 1; i <= 100;) {
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
diff --git a/net/quic/congestion_control/receive_algorithm_interface.cc b/net/quic/congestion_control/receive_algorithm_interface.cc
index 2154064..e8dacf0 100644
--- a/net/quic/congestion_control/receive_algorithm_interface.cc
+++ b/net/quic/congestion_control/receive_algorithm_interface.cc
@@ -14,9 +14,6 @@ ReceiveAlgorithmInterface* ReceiveAlgorithmInterface::Create(
const QuicClock* clock,
CongestionFeedbackType type) {
switch (type) {
- case kNone:
- LOG(DFATAL) << "Attempted to create a ReceiveAlgorithm with kNone.";
- break;
case kTCP:
return new TcpReceiver();
case kInterArrival:
diff --git a/net/quic/congestion_control/receive_algorithm_interface.h b/net/quic/congestion_control/receive_algorithm_interface.h
index e0c0713..461ec23 100644
--- a/net/quic/congestion_control/receive_algorithm_interface.h
+++ b/net/quic/congestion_control/receive_algorithm_interface.h
@@ -22,9 +22,10 @@ class NET_EXPORT_PRIVATE ReceiveAlgorithmInterface {
virtual ~ReceiveAlgorithmInterface() {}
- // Returns false if no CongestionInfo block is needed otherwise fills in
- // congestion_info and return true.
- virtual bool GenerateCongestionInfo(CongestionInfo* congestion_info) = 0;
+ // Returns false if no QuicCongestionFeedbackFrame block is needed.
+ // Otherwise fills in feedback and return true.
+ virtual bool GenerateCongestionFeedback(
+ QuicCongestionFeedbackFrame* feedback) = 0;
// Should be called for each incoming packet.
// bytes: is the packet size in bytes including IP headers.
diff --git a/net/quic/congestion_control/send_algorithm_interface.cc b/net/quic/congestion_control/send_algorithm_interface.cc
index e1155dc..9b794b0 100644
--- a/net/quic/congestion_control/send_algorithm_interface.cc
+++ b/net/quic/congestion_control/send_algorithm_interface.cc
@@ -16,9 +16,6 @@ SendAlgorithmInterface* SendAlgorithmInterface::Create(
const QuicClock* clock,
CongestionFeedbackType type) {
switch (type) {
- case kNone:
- LOG(DFATAL) << "Attempted to create a SendAlgorithm with kNone.";
- break;
case kTCP:
return new TcpCubicSender(clock, kUseReno);
case kInterArrival:
diff --git a/net/quic/congestion_control/send_algorithm_interface.h b/net/quic/congestion_control/send_algorithm_interface.h
index b42e678..5590d49 100644
--- a/net/quic/congestion_control/send_algorithm_interface.h
+++ b/net/quic/congestion_control/send_algorithm_interface.h
@@ -24,9 +24,9 @@ class NET_EXPORT_PRIVATE SendAlgorithmInterface {
virtual ~SendAlgorithmInterface() {}
- // Called when we receive congestion information from remote peer.
- virtual void OnIncomingCongestionInfo(
- const CongestionInfo& congestion_info) = 0;
+ // Called when we receive congestion feedback from remote peer.
+ virtual void OnIncomingQuicCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& feedback) = 0;
// Called for each received ACK, with sequence number from remote peer.
virtual void OnIncomingAck(QuicPacketSequenceNumber acked_sequence_number,
diff --git a/net/quic/congestion_control/tcp_cubic_sender.cc b/net/quic/congestion_control/tcp_cubic_sender.cc
index 92ddc18..7aab66c 100644
--- a/net/quic/congestion_control/tcp_cubic_sender.cc
+++ b/net/quic/congestion_control/tcp_cubic_sender.cc
@@ -33,21 +33,21 @@ TcpCubicSender::TcpCubicSender(const QuicClock* clock, bool reno)
delay_min_() {
}
-void TcpCubicSender::OnIncomingCongestionInfo(
- const CongestionInfo& congestion_info) {
+void TcpCubicSender::OnIncomingQuicCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& feedback) {
if (last_received_accumulated_number_of_lost_packets_ !=
- congestion_info.tcp.accumulated_number_of_lost_packets) {
+ feedback.tcp.accumulated_number_of_lost_packets) {
int recovered_lost_packets =
last_received_accumulated_number_of_lost_packets_ -
- congestion_info.tcp.accumulated_number_of_lost_packets;
+ feedback.tcp.accumulated_number_of_lost_packets;
last_received_accumulated_number_of_lost_packets_ =
- congestion_info.tcp.accumulated_number_of_lost_packets;
+ feedback.tcp.accumulated_number_of_lost_packets;
if (recovered_lost_packets > 0) {
OnIncomingLoss(recovered_lost_packets);
}
}
receiver_congestion_window_in_bytes_ =
- congestion_info.tcp.receive_window << 4;
+ feedback.tcp.receive_window << 4;
}
void TcpCubicSender::OnIncomingAck(
diff --git a/net/quic/congestion_control/tcp_cubic_sender.h b/net/quic/congestion_control/tcp_cubic_sender.h
index f850e06..bb2fe06 100644
--- a/net/quic/congestion_control/tcp_cubic_sender.h
+++ b/net/quic/congestion_control/tcp_cubic_sender.h
@@ -25,8 +25,8 @@ class NET_EXPORT_PRIVATE TcpCubicSender : public SendAlgorithmInterface {
TcpCubicSender(const QuicClock* clock, bool reno);
// Start implementation of SendAlgorithmInterface.
- virtual void OnIncomingCongestionInfo(
- const CongestionInfo& congestion_info) OVERRIDE;
+ virtual void OnIncomingQuicCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& feedback) OVERRIDE;
virtual void OnIncomingAck(QuicPacketSequenceNumber acked_sequence_number,
size_t acked_bytes,
QuicTime::Delta rtt) OVERRIDE;
diff --git a/net/quic/congestion_control/tcp_cubic_sender_test.cc b/net/quic/congestion_control/tcp_cubic_sender_test.cc
index 70adc96..1ec0072 100644
--- a/net/quic/congestion_control/tcp_cubic_sender_test.cc
+++ b/net/quic/congestion_control/tcp_cubic_sender_test.cc
@@ -58,15 +58,15 @@ class QuicTcpCubicSenderTest : public ::testing::Test {
};
TEST_F(QuicTcpCubicSenderTest, SimpleSender) {
- CongestionInfo info;
+ QuicCongestionFeedbackFrame feedback;
// At startup make sure we are at the default.
EXPECT_EQ(kDefaultWindowTCP,
sender_->AvailableCongestionWindow());
// At startup make sure we can send.
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
- // Get default CongestionInfo from receiver.
- ASSERT_TRUE(receiver_->GenerateCongestionInfo(&info));
- sender_->OnIncomingCongestionInfo(info);
+ // Get default QuicCongestionFeedbackFrame from receiver.
+ ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
+ sender_->OnIncomingQuicCongestionFeedbackFrame(feedback);
// Make sure we can send.
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
// And that window is un-affected.
@@ -78,12 +78,12 @@ TEST_F(QuicTcpCubicSenderTest, SimpleSender) {
TEST_F(QuicTcpCubicSenderTest, ExponentialSlowStart) {
const int kNumberOfAck = 20;
- CongestionInfo info;
+ QuicCongestionFeedbackFrame feedback;
// At startup make sure we can send.
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
- // Get default CongestionInfo from receiver.
- ASSERT_TRUE(receiver_->GenerateCongestionInfo(&info));
- sender_->OnIncomingCongestionInfo(info);
+ // Get default QuicCongestionFeedbackFrame from receiver.
+ ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
+ sender_->OnIncomingQuicCongestionFeedbackFrame(feedback);
// Make sure we can send.
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
@@ -104,12 +104,12 @@ TEST_F(QuicTcpCubicSenderTest, SlowStartAckTrain) {
// Since we start at 10 packet first round will be 5 second round 10 etc
// Hence we should pass 30 at 65 = 5 + 10 + 20 + 30
const int kNumberOfAck = 65;
- CongestionInfo info;
+ QuicCongestionFeedbackFrame feedback;
// At startup make sure we can send.
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
- // Get default CongestionInfo from receiver.
- ASSERT_TRUE(receiver_->GenerateCongestionInfo(&info));
- sender_->OnIncomingCongestionInfo(info);
+ // Get default QuicCongestionFeedbackFrame from receiver.
+ ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
+ sender_->OnIncomingQuicCongestionFeedbackFrame(feedback);
// Make sure we can send.
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
@@ -144,12 +144,12 @@ TEST_F(QuicTcpCubicSenderTest, SlowStartAckTrain) {
TEST_F(QuicTcpCubicSenderTest, SlowStartPacketLoss) {
// Make sure that we fall out of slow start when we encounter a packet loss.
const int kNumberOfAck = 10;
- CongestionInfo info;
+ QuicCongestionFeedbackFrame feedback;
// At startup make sure we can send.
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
- // Get default CongestionInfo from receiver.
- ASSERT_TRUE(receiver_->GenerateCongestionInfo(&info));
- sender_->OnIncomingCongestionInfo(info);
+ // Get default QuicCongestionFeedbackFrame from receiver.
+ ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
+ sender_->OnIncomingQuicCongestionFeedbackFrame(feedback);
// Make sure we can send.
EXPECT_TRUE(sender_->TimeUntilSend(false).IsZero());
diff --git a/net/quic/congestion_control/tcp_receiver.cc b/net/quic/congestion_control/tcp_receiver.cc
index f6b10cf..3401b21 100644
--- a/net/quic/congestion_control/tcp_receiver.cc
+++ b/net/quic/congestion_control/tcp_receiver.cc
@@ -15,11 +15,12 @@ TcpReceiver::TcpReceiver()
receive_window_in_bytes_(kReceiveWindowTCP) {
}
-bool TcpReceiver::GenerateCongestionInfo(CongestionInfo* congestion_info) {
- congestion_info->type = kTCP;
- congestion_info->tcp.accumulated_number_of_lost_packets =
+bool TcpReceiver::GenerateCongestionFeedback(
+ QuicCongestionFeedbackFrame* feedback) {
+ feedback->type = kTCP;
+ feedback->tcp.accumulated_number_of_lost_packets =
accumulated_number_of_recoverd_lost_packets_;
- congestion_info->tcp.receive_window = receive_window_in_bytes_ >> 4;
+ feedback->tcp.receive_window = receive_window_in_bytes_ >> 4;
return true;
}
diff --git a/net/quic/congestion_control/tcp_receiver.h b/net/quic/congestion_control/tcp_receiver.h
index 0bd58f1..48d781f 100644
--- a/net/quic/congestion_control/tcp_receiver.h
+++ b/net/quic/congestion_control/tcp_receiver.h
@@ -21,8 +21,8 @@ class NET_EXPORT_PRIVATE TcpReceiver : public ReceiveAlgorithmInterface {
TcpReceiver();
// Start implementation of SendAlgorithmInterface.
- virtual bool GenerateCongestionInfo(
- CongestionInfo* congestion_info) OVERRIDE;
+ virtual bool GenerateCongestionFeedback(
+ QuicCongestionFeedbackFrame* feedback) OVERRIDE;
virtual void RecordIncomingPacket(size_t bytes,
QuicPacketSequenceNumber sequence_number,
diff --git a/net/quic/congestion_control/tcp_receiver_test.cc b/net/quic/congestion_control/tcp_receiver_test.cc
index 6b8428f..ce2cbd7 100644
--- a/net/quic/congestion_control/tcp_receiver_test.cc
+++ b/net/quic/congestion_control/tcp_receiver_test.cc
@@ -20,18 +20,18 @@ class QuicTcpReceiverTest : public ::testing::Test {
};
TEST_F(QuicTcpReceiverTest, SimpleReceiver) {
- CongestionInfo info;
+ QuicCongestionFeedbackFrame feedback;
QuicTime timestamp;
receiver_->RecordIncomingPacket(1, 1, timestamp, false);
- ASSERT_TRUE(receiver_->GenerateCongestionInfo(&info));
- EXPECT_EQ(kTCP, info.type);
- EXPECT_EQ(256000, info.tcp.receive_window << 4);
- EXPECT_EQ(0, info.tcp.accumulated_number_of_lost_packets);
+ ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
+ EXPECT_EQ(kTCP, feedback.type);
+ EXPECT_EQ(256000, feedback.tcp.receive_window << 4);
+ EXPECT_EQ(0, feedback.tcp.accumulated_number_of_lost_packets);
receiver_->RecordIncomingPacket(1, 2, timestamp, true);
- ASSERT_TRUE(receiver_->GenerateCongestionInfo(&info));
- EXPECT_EQ(kTCP, info.type);
- EXPECT_EQ(256000, info.tcp.receive_window << 4);
- EXPECT_EQ(1, info.tcp.accumulated_number_of_lost_packets);
+ ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
+ EXPECT_EQ(kTCP, feedback.type);
+ EXPECT_EQ(256000, feedback.tcp.receive_window << 4);
+ EXPECT_EQ(1, feedback.tcp.accumulated_number_of_lost_packets);
}
} // namespace testing
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index 88964ad..ffa342e 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -81,7 +81,7 @@ QuicConnection::QuicConnection(QuicGuid guid,
memset(&last_header_, 0, sizeof(last_header_));
outgoing_ack_.sent_info.least_unacked = 0;
outgoing_ack_.received_info.largest_received = 0;
- outgoing_ack_.congestion_info.type = kNone;
+
/*
if (FLAGS_fake_packet_loss_percentage > 0) {
int32 seed = RandomBase::WeakSeed32();
@@ -125,7 +125,7 @@ void QuicConnection::OnRevivedPacket() {
bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
if (!Near(header.packet_sequence_number,
last_header_.packet_sequence_number)) {
- DVLOG(1) << "Packet out of bounds. Discarding";
+ DLOG(INFO) << "Packet out of bounds. Discarding";
// TODO(ianswett): Deal with this by truncating the ack packet instead of
// discarding the packet entirely.
return false;
@@ -186,6 +186,11 @@ void QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) {
}
}
+void QuicConnection::OnCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& feedback) {
+ scheduler_->OnIncomingQuicCongestionFeedbackFrame(feedback);
+}
+
bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
if (incoming_ack.received_info.largest_received >
packet_creator_.sequence_number()) {
@@ -619,10 +624,6 @@ bool QuicConnection::ShouldSimulateLostPacket() {
void QuicConnection::SendAck() {
packets_resent_since_last_ack_ = 0;
- if (!collector_->GenerateCongestionInfo(&outgoing_ack_.congestion_info)) {
- outgoing_ack_.congestion_info.type = kNone;
- }
-
if (!ContainsKey(unacked_packets_, outgoing_ack_.sent_info.least_unacked)) {
// At some point, all packets were acked, and we set least_unacked to a
// packet we will not resend. Make sure we update it.
@@ -635,6 +636,13 @@ void QuicConnection::SendAck() {
// Only send packet-timestamp pairs to the peer once, so clear them.
outgoing_ack_.received_info.ClearAckTimes();
SendPacket(packetpair.first, packetpair.second, false, false, false);
+
+ if (collector_->GenerateCongestionFeedback(&outgoing_congestion_feedback_)) {
+ DVLOG(1) << "Sending feedback " << outgoing_congestion_feedback_;
+ PacketPair packetpair = packet_creator_.CongestionFeedbackPacket(
+ &outgoing_congestion_feedback_);
+ SendPacket(packetpair.first, packetpair.second, false, false, false);
+ }
}
void QuicConnection::MaybeProcessRevivedPacket() {
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h
index 7b4570c..f98b4e2 100644
--- a/net/quic/quic_connection.h
+++ b/net/quic/quic_connection.h
@@ -152,6 +152,8 @@ class NET_EXPORT_PRIVATE QuicConnection : public QuicFramerVisitorInterface {
virtual void OnFecProtectedPayload(base::StringPiece payload) OVERRIDE;
virtual void OnStreamFrame(const QuicStreamFrame& frame) OVERRIDE;
virtual void OnAckFrame(const QuicAckFrame& frame) OVERRIDE;
+ virtual void OnCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& frame) OVERRIDE;
virtual void OnRstStreamFrame(const QuicRstStreamFrame& frame) OVERRIDE;
virtual void OnConnectionCloseFrame(
const QuicConnectionCloseFrame& frame) OVERRIDE;
@@ -297,6 +299,7 @@ protected:
std::vector<QuicStreamFrame> frames_;
QuicAckFrame outgoing_ack_;
+ QuicCongestionFeedbackFrame outgoing_congestion_feedback_;
// Track some client state so we can do less bookkeeping
//
diff --git a/net/quic/quic_connection_helper_test.cc b/net/quic/quic_connection_helper_test.cc
index 917ec1b..2e03ff2 100644
--- a/net/quic/quic_connection_helper_test.cc
+++ b/net/quic/quic_connection_helper_test.cc
@@ -133,27 +133,31 @@ class QuicConnectionHelperTest : public ::testing::Test {
QuicAckFrame ack(0, QuicTime(), sequence_number);
- ack.congestion_info.type = kTCP;
- ack.congestion_info.tcp.accumulated_number_of_lost_packets = 0;
- ack.congestion_info.tcp.receive_window = 16000;
return ConstructPacket(header_, QuicFrame(&ack));
}
+
+ // Returns a newly created packet to send congestion feedback data.
+ QuicEncryptedPacket* ConstructFeedbackPacket(
+ QuicPacketSequenceNumber sequence_number) {
+ InitializeHeader(sequence_number);
+
+ QuicCongestionFeedbackFrame frame;
+ frame.type = kTCP;
+ frame.tcp.accumulated_number_of_lost_packets = 0;
+ frame.tcp.receive_window = 16000;
+
+ return ConstructPacket(header_, QuicFrame(&frame));
+ }
+
// Returns a newly created packet to send a connection close frame.
QuicEncryptedPacket* ConstructClosePacket(
QuicPacketSequenceNumber sequence_number,
- bool with_ack) {
+ QuicPacketSequenceNumber least_waiting) {
InitializeHeader(sequence_number);
QuicFrames frames;
- QuicAckFrame ack(0, QuicTime(), sequence_number - 1);
- if (with_ack) {
- ack.congestion_info.type = kTCP;
- ack.congestion_info.tcp.accumulated_number_of_lost_packets = 0;
- ack.congestion_info.tcp.receive_window = 16000;
- } else {
- ack.congestion_info.type = kNone;
- }
+ QuicAckFrame ack(0, QuicTime(), least_waiting);
QuicConnectionCloseFrame close;
close.error_code = QUIC_CONNECTION_TIMED_OUT;
close.ack_frame = ack;
@@ -237,7 +241,7 @@ TEST_F(QuicConnectionHelperTest, TestResend) {
}
TEST_F(QuicConnectionHelperTest, InitialTimeout) {
- AddWrite(SYNCHRONOUS, ConstructClosePacket(1, false));
+ AddWrite(SYNCHRONOUS, ConstructClosePacket(1, 0));
Initialize();
// Verify that a single task was posted.
@@ -267,7 +271,7 @@ TEST_F(QuicConnectionHelperTest, WritePacketToWire) {
}
TEST_F(QuicConnectionHelperTest, WritePacketToWireAsync) {
- AddWrite(ASYNC, ConstructClosePacket(1, false));
+ AddWrite(ASYNC, ConstructClosePacket(1, 0));
Initialize();
EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(testing::Return(true));
@@ -281,7 +285,8 @@ TEST_F(QuicConnectionHelperTest, WritePacketToWireAsync) {
TEST_F(QuicConnectionHelperTest, TimeoutAfterSend) {
AddWrite(SYNCHRONOUS, ConstructAckPacket(1));
- AddWrite(SYNCHRONOUS, ConstructClosePacket(2, true));
+ AddWrite(SYNCHRONOUS, ConstructFeedbackPacket(2));
+ AddWrite(SYNCHRONOUS, ConstructClosePacket(3, 1));
Initialize();
EXPECT_TRUE(connection_->connected());
@@ -291,11 +296,11 @@ TEST_F(QuicConnectionHelperTest, TimeoutAfterSend) {
clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(5000));
EXPECT_EQ(5000u, clock_.Now().ToMicroseconds());
EXPECT_CALL(*scheduler_, SentPacket(1, _, false));
+ EXPECT_CALL(*scheduler_, SentPacket(2, _, false));
// Send an ack so we don't set the resend alarm.
connection_->SendAck();
- EXPECT_CALL(*scheduler_, SentPacket(2, _, false));
// The original alarm will fire. We should not time out because we had a
// network event at t=5000. The alarm will reregister.
runner_->RunNextTask();
@@ -305,6 +310,7 @@ TEST_F(QuicConnectionHelperTest, TimeoutAfterSend) {
// This time, we should time out.
EXPECT_CALL(visitor_, ConnectionClose(QUIC_CONNECTION_TIMED_OUT, false));
+ EXPECT_CALL(*scheduler_, SentPacket(3, _, false));
runner_->RunNextTask();
EXPECT_EQ(kDefaultTimeoutUs + 5000, clock_.Now().ToMicroseconds());
EXPECT_FALSE(connection_->connected());
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index 1facb1f..3938050 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -57,16 +57,17 @@ const char data2[] = "bar";
class TestCollector : public QuicReceiptMetricsCollector {
public:
- explicit TestCollector(CongestionInfo* info)
+ explicit TestCollector(QuicCongestionFeedbackFrame* feedback)
: QuicReceiptMetricsCollector(&clock_, kFixRate),
- info_(info) {
+ feedback_(feedback) {
}
- bool GenerateCongestionInfo(CongestionInfo* congestion_info) {
- if (info_ == NULL) {
+ bool GenerateCongestionFeedback(
+ QuicCongestionFeedbackFrame* congestion_feedback) {
+ if (feedback_ == NULL) {
return false;
}
- *congestion_info = *info_;
+ *congestion_feedback = *feedback_;
return true;
}
@@ -75,7 +76,7 @@ class TestCollector : public QuicReceiptMetricsCollector {
private:
MockClock clock_;
- CongestionInfo* info_;
+ QuicCongestionFeedbackFrame* feedback_;
DISALLOW_COPY_AND_ASSIGN(TestCollector);
};
@@ -102,7 +103,12 @@ class TestConnectionHelper : public QuicConnectionHelperInterface {
framer.set_visitor(&visitor);
EXPECT_TRUE(framer.ProcessPacket(IPEndPoint(), IPEndPoint(), packet));
header_ = *visitor.header();
- frame_ = *visitor.frame();
+ if (visitor.ack()) {
+ ack_.reset(new QuicAckFrame(*visitor.ack()));
+ }
+ if (visitor.feedback()) {
+ feedback_.reset(new QuicCongestionFeedbackFrame(*visitor.feedback()));
+ }
if (blocked_) {
*error = ERR_IO_PENDING;
return -1;
@@ -139,7 +145,9 @@ class TestConnectionHelper : public QuicConnectionHelperInterface {
QuicPacketHeader* header() { return &header_; }
- QuicAckFrame* frame() { return &frame_; }
+ QuicAckFrame* ack() { return ack_.get(); }
+
+ QuicCongestionFeedbackFrame* feedback() { return feedback_.get(); }
void set_blocked(bool blocked) { blocked_ = blocked; }
@@ -149,7 +157,8 @@ class TestConnectionHelper : public QuicConnectionHelperInterface {
QuicTime send_alarm_;
QuicTime timeout_alarm_;
QuicPacketHeader header_;
- QuicAckFrame frame_;
+ scoped_ptr<QuicAckFrame> ack_;
+ scoped_ptr<QuicCongestionFeedbackFrame> feedback_;
bool blocked_;
DISALLOW_COPY_AND_ASSIGN(TestConnectionHelper);
@@ -202,12 +211,18 @@ class QuicConnectionTest : public ::testing::Test {
accept_packet_(true) {
connection_.set_visitor(&visitor_);
connection_.SetScheduler(scheduler_);
+ // Simplify tests by not sending feedback unless specifically configured.
+ SetFeedback(NULL);
EXPECT_CALL(*scheduler_, TimeUntilSend(_)).WillRepeatedly(Return(
QuicTime::Delta()));
}
- QuicAckFrame* last_frame() {
- return helper_->frame();
+ QuicAckFrame* last_ack() {
+ return helper_->ack();
+ }
+
+ QuicCongestionFeedbackFrame* last_feedback() {
+ return helper_->feedback();
}
QuicPacketHeader* last_header() {
@@ -290,7 +305,7 @@ class QuicConnectionTest : public ::testing::Test {
}
void SendAckPacketToPeer() {
- EXPECT_CALL(*scheduler_, SentPacket(_, _, _));
+ EXPECT_CALL(*scheduler_, SentPacket(_, _, _)).Times(num_packets_per_ack_);
connection_.SendAck();
}
@@ -304,7 +319,7 @@ class QuicConnectionTest : public ::testing::Test {
}
bool IsMissing(QuicPacketSequenceNumber number) {
- return last_frame()->received_info.IsAwaitingPacket(number);
+ return last_ack()->received_info.IsAwaitingPacket(number);
}
QuicPacket* ConstructDataPacket(QuicPacketSequenceNumber number,
@@ -322,11 +337,18 @@ class QuicConnectionTest : public ::testing::Test {
return packet;
}
+ void SetFeedback(QuicCongestionFeedbackFrame* feedback) {
+ num_packets_per_ack_ = feedback != NULL ? 2 : 1;
+ collector_ = new TestCollector(feedback);
+ connection_.SetCollector(collector_);
+ }
+
QuicGuid guid_;
QuicFramer framer_;
QuicPacketCreator creator_;
MockScheduler* scheduler_;
+ TestCollector* collector_;
MockClock clock_;
scoped_ptr<TestConnectionHelper> helper_;
TestConnection connection_;
@@ -336,6 +358,7 @@ class QuicConnectionTest : public ::testing::Test {
QuicStreamFrame frame1_;
QuicStreamFrame frame2_;
bool accept_packet_;
+ size_t num_packets_per_ack_;
private:
DISALLOW_COPY_AND_ASSIGN(QuicConnectionTest);
@@ -343,86 +366,86 @@ class QuicConnectionTest : public ::testing::Test {
TEST_F(QuicConnectionTest, PacketsInOrder) {
ProcessPacket(1);
- EXPECT_EQ(1u, last_frame()->received_info.largest_received);
- EXPECT_EQ(1u, last_frame()->received_info.received_packet_times.size());
- EXPECT_EQ(0u, last_frame()->received_info.missing_packets.size());
+ EXPECT_EQ(1u, last_ack()->received_info.largest_received);
+ EXPECT_EQ(1u, last_ack()->received_info.received_packet_times.size());
+ EXPECT_EQ(0u, last_ack()->received_info.missing_packets.size());
ProcessPacket(2);
- EXPECT_EQ(2u, last_frame()->received_info.largest_received);
- EXPECT_EQ(1u, last_frame()->received_info.received_packet_times.size());
- EXPECT_EQ(0u, last_frame()->received_info.missing_packets.size());
+ EXPECT_EQ(2u, last_ack()->received_info.largest_received);
+ EXPECT_EQ(1u, last_ack()->received_info.received_packet_times.size());
+ EXPECT_EQ(0u, last_ack()->received_info.missing_packets.size());
ProcessPacket(3);
- EXPECT_EQ(3u, last_frame()->received_info.largest_received);
- EXPECT_EQ(1u, last_frame()->received_info.received_packet_times.size());
- EXPECT_EQ(0u, last_frame()->received_info.missing_packets.size());
+ EXPECT_EQ(3u, last_ack()->received_info.largest_received);
+ EXPECT_EQ(1u, last_ack()->received_info.received_packet_times.size());
+ EXPECT_EQ(0u, last_ack()->received_info.missing_packets.size());
}
TEST_F(QuicConnectionTest, PacketsRejected) {
ProcessPacket(1);
- EXPECT_EQ(1u, last_frame()->received_info.largest_received);
- EXPECT_EQ(1u, last_frame()->received_info.received_packet_times.size());
- EXPECT_EQ(0u, last_frame()->received_info.missing_packets.size());
+ EXPECT_EQ(1u, last_ack()->received_info.largest_received);
+ EXPECT_EQ(1u, last_ack()->received_info.received_packet_times.size());
+ EXPECT_EQ(0u, last_ack()->received_info.missing_packets.size());
accept_packet_ = false;
ProcessPacket(2);
// We should not have an ack for two.
- EXPECT_EQ(1u, last_frame()->received_info.largest_received);
- EXPECT_EQ(0u, last_frame()->received_info.received_packet_times.size());
- EXPECT_EQ(0u, last_frame()->received_info.missing_packets.size());
+ EXPECT_EQ(1u, last_ack()->received_info.largest_received);
+ EXPECT_EQ(0u, last_ack()->received_info.received_packet_times.size());
+ EXPECT_EQ(0u, last_ack()->received_info.missing_packets.size());
}
TEST_F(QuicConnectionTest, PacketsOutOfOrder) {
ProcessPacket(3);
- EXPECT_EQ(3u, last_frame()->received_info.largest_received);
- EXPECT_EQ(1u, last_frame()->received_info.received_packet_times.size());
+ EXPECT_EQ(3u, last_ack()->received_info.largest_received);
+ EXPECT_EQ(1u, last_ack()->received_info.received_packet_times.size());
EXPECT_TRUE(IsMissing(2));
EXPECT_TRUE(IsMissing(1));
ProcessPacket(2);
- EXPECT_EQ(3u, last_frame()->received_info.largest_received);
- EXPECT_EQ(1u, last_frame()->received_info.received_packet_times.size());
+ EXPECT_EQ(3u, last_ack()->received_info.largest_received);
+ EXPECT_EQ(1u, last_ack()->received_info.received_packet_times.size());
EXPECT_FALSE(IsMissing(2));
EXPECT_TRUE(IsMissing(1));
ProcessPacket(1);
- EXPECT_EQ(3u, last_frame()->received_info.largest_received);
- EXPECT_EQ(1u, last_frame()->received_info.received_packet_times.size());
+ EXPECT_EQ(3u, last_ack()->received_info.largest_received);
+ EXPECT_EQ(1u, last_ack()->received_info.received_packet_times.size());
EXPECT_FALSE(IsMissing(2));
EXPECT_FALSE(IsMissing(1));
}
TEST_F(QuicConnectionTest, DuplicatePacket) {
ProcessPacket(3);
- EXPECT_EQ(3u, last_frame()->received_info.largest_received);
- EXPECT_EQ(1u, last_frame()->received_info.received_packet_times.size());
+ EXPECT_EQ(3u, last_ack()->received_info.largest_received);
+ EXPECT_EQ(1u, last_ack()->received_info.received_packet_times.size());
EXPECT_TRUE(IsMissing(2));
EXPECT_TRUE(IsMissing(1));
// Send packet 3 again, but do not set the expectation that
// the visitor OnPacket() will be called.
ProcessDataPacket(3, 0);
- EXPECT_EQ(3u, last_frame()->received_info.largest_received);
- EXPECT_EQ(1u, last_frame()->received_info.received_packet_times.size());
+ EXPECT_EQ(3u, last_ack()->received_info.largest_received);
+ EXPECT_EQ(1u, last_ack()->received_info.received_packet_times.size());
EXPECT_TRUE(IsMissing(2));
EXPECT_TRUE(IsMissing(1));
}
TEST_F(QuicConnectionTest, PacketsOutOfOrderWithAdditionsAndLeastAwaiting) {
ProcessPacket(3);
- EXPECT_EQ(3u, last_frame()->received_info.largest_received);
- EXPECT_EQ(1u, last_frame()->received_info.received_packet_times.size());
+ EXPECT_EQ(3u, last_ack()->received_info.largest_received);
+ EXPECT_EQ(1u, last_ack()->received_info.received_packet_times.size());
EXPECT_TRUE(IsMissing(2));
EXPECT_TRUE(IsMissing(1));
ProcessPacket(2);
- EXPECT_EQ(3u, last_frame()->received_info.largest_received);
- EXPECT_EQ(1u, last_frame()->received_info.received_packet_times.size());
+ EXPECT_EQ(3u, last_ack()->received_info.largest_received);
+ EXPECT_EQ(1u, last_ack()->received_info.received_packet_times.size());
EXPECT_TRUE(IsMissing(1));
ProcessPacket(5);
- EXPECT_EQ(5u, last_frame()->received_info.largest_received);
- EXPECT_EQ(1u, last_frame()->received_info.received_packet_times.size());
+ EXPECT_EQ(5u, last_ack()->received_info.largest_received);
+ EXPECT_EQ(1u, last_ack()->received_info.received_packet_times.size());
EXPECT_TRUE(IsMissing(1));
EXPECT_TRUE(IsMissing(4));
@@ -437,7 +460,7 @@ TEST_F(QuicConnectionTest, PacketsOutOfOrderWithAdditionsAndLeastAwaiting) {
// Force an ack to be sent.
SendAckPacketToPeer();
// 1 because the only received packet is the ack packet itself.
- EXPECT_EQ(1u, last_frame()->received_info.received_packet_times.size());
+ EXPECT_EQ(1u, last_ack()->received_info.received_packet_times.size());
EXPECT_TRUE(IsMissing(4));
}
@@ -447,7 +470,7 @@ TEST_F(QuicConnectionTest, RejectPacketTooFarOut) {
ProcessDataPacket(6000, 0);
SendAckPacketToPeer(); // Packet 2
- EXPECT_EQ(0u, last_frame()->received_info.largest_received);
+ EXPECT_EQ(0u, last_ack()->received_info.largest_received);
}
TEST_F(QuicConnectionTest, LeastUnackedLower) {
@@ -530,15 +553,15 @@ TEST_F(QuicConnectionTest, BasicSending) {
EXPECT_EQ(1u, last_packet);
SendAckPacketToPeer(); // Packet 2
- EXPECT_EQ(1u, last_frame()->sent_info.least_unacked);
+ EXPECT_EQ(1u, last_ack()->sent_info.least_unacked);
SendAckPacketToPeer(); // Packet 3
- EXPECT_EQ(1u, last_frame()->sent_info.least_unacked);
+ EXPECT_EQ(1u, last_ack()->sent_info.least_unacked);
SendStreamDataToPeer(1u, "bar", 3, false, &last_packet); // Packet 4
EXPECT_EQ(4u, last_packet);
SendAckPacketToPeer(); // Packet 5
- EXPECT_EQ(1u, last_frame()->sent_info.least_unacked);
+ EXPECT_EQ(1u, last_ack()->sent_info.least_unacked);
QuicConnectionVisitorInterface::AckedPackets expected_acks;
expected_acks.insert(1);
@@ -551,7 +574,7 @@ TEST_F(QuicConnectionTest, BasicSending) {
// As soon as we've acked one, we skip ack packets 2 and 3 and note lack of
// ack for 4.
- EXPECT_EQ(4u, last_frame()->sent_info.least_unacked);
+ EXPECT_EQ(4u, last_ack()->sent_info.least_unacked);
expected_acks.clear();
expected_acks.insert(4);
@@ -563,17 +586,17 @@ TEST_F(QuicConnectionTest, BasicSending) {
SendAckPacketToPeer(); // Packet 7
// The least packet awaiting ack should now be 7
- EXPECT_EQ(7u, last_frame()->sent_info.least_unacked);
+ EXPECT_EQ(7u, last_ack()->sent_info.least_unacked);
// If we force an ack, we shouldn't change our retransmit state.
SendAckPacketToPeer(); // Packet 8
- EXPECT_EQ(8u, last_frame()->sent_info.least_unacked);
+ EXPECT_EQ(8u, last_ack()->sent_info.least_unacked);
// But if we send more data it should.
SendStreamDataToPeer(1, "eep", 6, false, &last_packet); // Packet 9
EXPECT_EQ(9u, last_packet);
SendAckPacketToPeer(); // Packet10
- EXPECT_EQ(9u, last_frame()->sent_info.least_unacked);
+ EXPECT_EQ(9u, last_ack()->sent_info.least_unacked);
}
TEST_F(QuicConnectionTest, ResendOnNack) {
@@ -701,10 +724,9 @@ TEST_F(QuicConnectionTest, DontLatchUnackedPacket) {
// set it to 3.
SendAckPacketToPeer(); // Packet 3
EXPECT_EQ(3u, outgoing_ack->sent_info.least_unacked);
- EXPECT_EQ(3u, last_frame()->sent_info.least_unacked);
+ EXPECT_EQ(3u, last_ack()->sent_info.least_unacked);
}
-
TEST_F(QuicConnectionTest, ReviveMissingPacketAfterFecPacket) {
// Don't send missing packet 1.
ProcessFecPacket(2, 1, true);
@@ -795,40 +817,34 @@ TEST_F(QuicConnectionTest, CloseFecGroup) {
ASSERT_EQ(0u, connection_.NumFecGroups());
}
-TEST_F(QuicConnectionTest, NoCongestionInfo) {
- TestCollector* collector(new TestCollector(NULL));
- connection_.SetCollector(collector);
+TEST_F(QuicConnectionTest, NoQuicCongestionFeedbackFrame) {
SendAckPacketToPeer();
- EXPECT_EQ(kNone, last_frame()->congestion_info.type);
+ EXPECT_TRUE(last_feedback() == NULL);
}
-TEST_F(QuicConnectionTest, WithCongestionInfo) {
- CongestionInfo info;
+TEST_F(QuicConnectionTest, WithQuicCongestionFeedbackFrame) {
+ QuicCongestionFeedbackFrame info;
info.type = kFixRate;
info.fix_rate.bitrate_in_bytes_per_second = 123;
- TestCollector* collector(new TestCollector(&info));
- connection_.SetCollector(collector);
+ SetFeedback(&info);
+
SendAckPacketToPeer();
- EXPECT_EQ(kFixRate, last_frame()->congestion_info.type);
+ EXPECT_EQ(kFixRate, last_feedback()->type);
EXPECT_EQ(info.fix_rate.bitrate_in_bytes_per_second,
- last_frame()->congestion_info.fix_rate.bitrate_in_bytes_per_second);
+ last_feedback()->fix_rate.bitrate_in_bytes_per_second);
}
-TEST_F(QuicConnectionTest, UpdateCongestionInfo) {
- TestCollector* collector(new TestCollector(NULL));
- connection_.SetCollector(collector);
+TEST_F(QuicConnectionTest, UpdateQuicCongestionFeedbackFrame) {
SendAckPacketToPeer();
- EXPECT_CALL(*collector, RecordIncomingPacket(_, _, _, _));
+ EXPECT_CALL(*collector_, RecordIncomingPacket(_, _, _, _));
ProcessPacket(1);
}
-TEST_F(QuicConnectionTest, DontUpdateCongestionInfoForRevived) {
- TestCollector* collector(new TestCollector(NULL));
- connection_.SetCollector(collector);
+TEST_F(QuicConnectionTest, DontUpdateQuicCongestionFeedbackFrameForRevived) {
SendAckPacketToPeer();
// Process an FEC packet, and revive the missing data packet
// but only contact the collector once.
- EXPECT_CALL(*collector, RecordIncomingPacket(_, _, _, _));
+ EXPECT_CALL(*collector_, RecordIncomingPacket(_, _, _, _));
ProcessFecPacket(2, 1, true);
}
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
index 0de0a40..4223196 100644
--- a/net/quic/quic_framer.cc
+++ b/net/quic/quic_framer.cc
@@ -74,6 +74,12 @@ bool QuicFramer::ConstructFrameDataPacket(
return false;
}
break;
+ case CONGESTION_FEEDBACK_FRAME:
+ if (!AppendQuicCongestionFeedbackFramePayload(
+ *frame.congestion_feedback_frame, &writer)) {
+ return false;
+ }
+ break;
case RST_STREAM_FRAME:
if (!AppendRstStreamFramePayload(*frame.rst_stream_frame,
&writer)) {
@@ -302,6 +308,13 @@ bool QuicFramer::ProcessFrameData() {
}
break;
}
+ case CONGESTION_FEEDBACK_FRAME: {
+ QuicCongestionFeedbackFrame frame;
+ if (!ProcessQuicCongestionFeedbackFrame(&frame)) {
+ return RaiseError(QUIC_INVALID_FRAME_DATA);
+ }
+ break;
+ }
case RST_STREAM_FRAME:
if (!ProcessRstStreamFrame()) {
return RaiseError(QUIC_INVALID_RST_STREAM_DATA);
@@ -365,9 +378,6 @@ bool QuicFramer::ProcessAckFrame(QuicAckFrame* frame) {
if (!ProcessSentInfo(&frame->sent_info)) {
return false;
}
- if (!ProcessCongestionInfo(&frame->congestion_info)) {
- return false;
- }
visitor_->OnAckFrame(*frame);
return true;
}
@@ -443,21 +453,20 @@ bool QuicFramer::ProcessSentInfo(SentPacketInfo* sent_info) {
return true;
}
-bool QuicFramer::ProcessCongestionInfo(CongestionInfo* congestion_info) {
- uint8 congestion_info_type;
- if (!reader_->ReadBytes(&congestion_info_type, 1)) {
- set_detailed_error("Unable to read congestion info type.");
+bool QuicFramer::ProcessQuicCongestionFeedbackFrame(
+ QuicCongestionFeedbackFrame* frame) {
+ uint8 feedback_type;
+ if (!reader_->ReadBytes(&feedback_type, 1)) {
+ set_detailed_error("Unable to read congestion feedback type.");
return false;
}
- congestion_info->type =
- static_cast<CongestionFeedbackType>(congestion_info_type);
+ frame->type =
+ static_cast<CongestionFeedbackType>(feedback_type);
- switch (congestion_info->type) {
- case kNone:
- break;
+ switch (frame->type) {
case kInterArrival: {
CongestionFeedbackMessageInterArrival* inter_arrival =
- &congestion_info->inter_arrival;
+ &frame->inter_arrival;
if (!reader_->ReadUInt16(
&inter_arrival->accumulated_number_of_lost_packets)) {
set_detailed_error(
@@ -475,7 +484,7 @@ bool QuicFramer::ProcessCongestionInfo(CongestionInfo* congestion_info) {
break;
}
case kFixRate: {
- CongestionFeedbackMessageFixRate* fix_rate = &congestion_info->fix_rate;
+ CongestionFeedbackMessageFixRate* fix_rate = &frame->fix_rate;
if (!reader_->ReadUInt32(&fix_rate->bitrate_in_bytes_per_second)) {
set_detailed_error("Unable to read bitrate.");
return false;
@@ -483,7 +492,7 @@ bool QuicFramer::ProcessCongestionInfo(CongestionInfo* congestion_info) {
break;
}
case kTCP: {
- CongestionFeedbackMessageTCP* tcp = &congestion_info->tcp;
+ CongestionFeedbackMessageTCP* tcp = &frame->tcp;
if (!reader_->ReadUInt16(&tcp->accumulated_number_of_lost_packets)) {
set_detailed_error(
"Unable to read accumulated number of lost packets.");
@@ -496,12 +505,13 @@ bool QuicFramer::ProcessCongestionInfo(CongestionInfo* congestion_info) {
break;
}
default:
- set_detailed_error("Illegal congestion info type.");
- DLOG(WARNING) << "Illegal congestion info type: "
- << congestion_info->type;
+ set_detailed_error("Illegal congestion feedback type.");
+ DLOG(WARNING) << "Illegal congestion feedback type: "
+ << frame->type;
return RaiseError(QUIC_INVALID_FRAME_DATA);
}
+ visitor_->OnCongestionFeedbackFrame(*frame);
return true;
}
@@ -635,10 +645,14 @@ size_t QuicFramer::ComputeFramePayloadLength(const QuicFrame& frame) {
len += 6 * (ack.received_info.received_packet_times.size() - 1);
}
len += 6; // least packet sequence number awaiting an ack
- len += 1; // congestion control type
- switch (ack.congestion_info.type) {
- case kNone:
break;
+ }
+ case CONGESTION_FEEDBACK_FRAME: {
+ const QuicCongestionFeedbackFrame& congestion_feedback =
+ *frame.congestion_feedback_frame;
+ len += 1; // congestion feedback type
+
+ switch (congestion_feedback.type) {
case kInterArrival:
len += 6;
break;
@@ -650,7 +664,7 @@ size_t QuicFramer::ComputeFramePayloadLength(const QuicFrame& frame) {
break;
default:
set_detailed_error("Illegal feedback type.");
- DLOG(INFO) << "Illegal feedback type: " << ack.congestion_info.type;
+ DLOG(INFO) << "Illegal feedback type: " << congestion_feedback.type;
break;
}
break;
@@ -771,16 +785,20 @@ bool QuicFramer::AppendAckFramePayload(
return false;
}
- if (!writer->WriteBytes(&frame.congestion_info.type, 1)) {
+ return true;
+}
+
+bool QuicFramer::AppendQuicCongestionFeedbackFramePayload(
+ const QuicCongestionFeedbackFrame& frame,
+ QuicDataWriter* writer) {
+ if (!writer->WriteBytes(&frame.type, 1)) {
return false;
}
- switch (frame.congestion_info.type) {
- case kNone:
- break;
+ switch (frame.type) {
case kInterArrival: {
const CongestionFeedbackMessageInterArrival& inter_arrival =
- frame.congestion_info.inter_arrival;
+ frame.inter_arrival;
if (!writer->WriteUInt16(
inter_arrival.accumulated_number_of_lost_packets)) {
return false;
@@ -795,14 +813,14 @@ bool QuicFramer::AppendAckFramePayload(
}
case kFixRate: {
const CongestionFeedbackMessageFixRate& fix_rate =
- frame.congestion_info.fix_rate;
+ frame.fix_rate;
if (!writer->WriteUInt32(fix_rate.bitrate_in_bytes_per_second)) {
return false;
}
break;
}
case kTCP: {
- const CongestionFeedbackMessageTCP& tcp = frame.congestion_info.tcp;
+ const CongestionFeedbackMessageTCP& tcp = frame.tcp;
if (!writer->WriteUInt16(tcp.accumulated_number_of_lost_packets)) {
return false;
}
diff --git a/net/quic/quic_framer.h b/net/quic/quic_framer.h
index 9afbdff..2b58165 100644
--- a/net/quic/quic_framer.h
+++ b/net/quic/quic_framer.h
@@ -56,6 +56,10 @@ class NET_EXPORT_PRIVATE QuicFramerVisitorInterface {
// Called when a AckFrame has been parsed.
virtual void OnAckFrame(const QuicAckFrame& frame) = 0;
+ // Called when a CongestionFeedbackFrame has been parsed.
+ virtual void OnCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& frame) = 0;
+
// Called when a RstStreamFrame has been parsed.
virtual void OnRstStreamFrame(const QuicRstStreamFrame& frame) = 0;
@@ -167,7 +171,8 @@ class NET_EXPORT_PRIVATE QuicFramer {
bool ProcessAckFrame(QuicAckFrame* frame);
bool ProcessReceivedInfo(ReceivedPacketInfo* received_info);
bool ProcessSentInfo(SentPacketInfo* sent_info);
- bool ProcessCongestionInfo(CongestionInfo* congestion_info);
+ bool ProcessQuicCongestionFeedbackFrame(
+ QuicCongestionFeedbackFrame* congestion_feedback);
bool ProcessRstStreamFrame();
bool ProcessConnectionCloseFrame();
@@ -180,6 +185,9 @@ class NET_EXPORT_PRIVATE QuicFramer {
QuicDataWriter* builder);
bool AppendAckFramePayload(const QuicAckFrame& frame,
QuicDataWriter* builder);
+ bool AppendQuicCongestionFeedbackFramePayload(
+ const QuicCongestionFeedbackFrame& frame,
+ QuicDataWriter* builder);
bool AppendRstStreamFramePayload(const QuicRstStreamFrame& frame,
QuicDataWriter* builder);
bool AppendConnectionCloseFramePayload(
diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc
index 43a05aa..e25beed 100644
--- a/net/quic/quic_framer_test.cc
+++ b/net/quic/quic_framer_test.cc
@@ -59,10 +59,6 @@ class TestDecrypter : public QuicDecrypter {
string ciphertext_;
};
-// The offset of congestion info in our tests, given the size of our usual ack
-// frame. This does NOT work for all packets.
-const int kCongestionInfoOffset = kPacketHeaderSize + 48;
-
class TestQuicVisitor : public ::net::QuicFramerVisitorInterface {
public:
TestQuicVisitor()
@@ -78,6 +74,7 @@ class TestQuicVisitor : public ::net::QuicFramerVisitorInterface {
~TestQuicVisitor() {
STLDeleteElements(&stream_frames_);
STLDeleteElements(&ack_frames_);
+ STLDeleteElements(&congestion_feedback_frames_);
STLDeleteElements(&fec_data_);
}
@@ -117,6 +114,13 @@ class TestQuicVisitor : public ::net::QuicFramerVisitorInterface {
ack_frames_.push_back(new QuicAckFrame(frame));
}
+ virtual void OnCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& frame) {
+ frame_count_++;
+ congestion_feedback_frames_.push_back(
+ new QuicCongestionFeedbackFrame(frame));
+ }
+
virtual void OnFecData(const QuicFecData& fec) {
fec_count_++;
fec_data_.push_back(new QuicFecData(fec));
@@ -149,6 +153,7 @@ class TestQuicVisitor : public ::net::QuicFramerVisitorInterface {
scoped_ptr<QuicPacketHeader> header_;
vector<QuicStreamFrame*> stream_frames_;
vector<QuicAckFrame*> ack_frames_;
+ vector<QuicCongestionFeedbackFrame*> congestion_feedback_frames_;
vector<QuicFecData*> fec_data_;
string fec_protected_payload_;
QuicRstStreamFrame rst_stream_frame_;
@@ -355,22 +360,23 @@ TEST_F(QuicFramerTest, StreamFrame) {
EXPECT_EQ("hello world!", visitor_.stream_frames_[0]->data);
// Now test framing boundaries
- for (size_t i = kPacketHeaderSize; i < kPacketHeaderSize + 29; ++i) {
+ for (size_t i = 0; i < 29; ++i) {
string expected_error;
- if (i < kPacketHeaderSize + 1) {
+ if (i < 1) {
expected_error = "Unable to read frame count.";
- } else if (i < kPacketHeaderSize + 2) {
+ } else if (i < 2) {
expected_error = "Unable to read frame type.";
- } else if (i < kPacketHeaderSize + 6) {
+ } else if (i < 6) {
expected_error = "Unable to read stream_id.";
- } else if (i < kPacketHeaderSize + 7) {
+ } else if (i < 7) {
expected_error = "Unable to read fin.";
- } else if (i < kPacketHeaderSize + 15) {
+ } else if (i < 15) {
expected_error = "Unable to read offset.";
- } else if (i < kPacketHeaderSize + 29) {
+ } else if (i < 29) {
expected_error = "Unable to read frame data.";
}
- CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_FRAME_DATA);
+ CheckProcessingFails(packet, i + kPacketHeaderSize, expected_error,
+ QUIC_INVALID_FRAME_DATA);
}
}
@@ -568,8 +574,6 @@ TEST_F(QuicFramerTest, AckFrame) {
// least packet sequence number awaiting an ack
0xA0, 0x9A, 0x78, 0x56,
0x34, 0x12,
- // congestion feedback type (none)
- 0x00,
};
QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -603,45 +607,43 @@ TEST_F(QuicFramerTest, AckFrame) {
iter->second);
EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame.sent_info.least_unacked);
- ASSERT_EQ(kNone, frame.congestion_info.type);
// Now test framing boundaries
- for (size_t i = kPacketHeaderSize; i < kPacketHeaderSize + 49; ++i) {
+ for (size_t i = 0; i < 48; ++i) {
string expected_error;
- if (i < kPacketHeaderSize + 1) {
+ if (i < 1) {
expected_error = "Unable to read frame count.";
- } else if (i < kPacketHeaderSize + 2) {
+ } else if (i < 2) {
expected_error = "Unable to read frame type.";
- } else if (i < kPacketHeaderSize + 8) {
+ } else if (i < 8) {
expected_error = "Unable to read largest received.";
- } else if (i < kPacketHeaderSize + 9) {
+ } else if (i < 9) {
expected_error = "Unable to read num unacked packets.";
- } else if (i < kPacketHeaderSize + 15) {
+ } else if (i < 15) {
expected_error = "Unable to read sequence number in unacked packets.";
- } else if (i < kPacketHeaderSize + 16) {
+ } else if (i < 16) {
expected_error = "Unable to read num acked packets.";
- } else if (i < kPacketHeaderSize + 22) {
+ } else if (i < 22) {
expected_error = "Unable to read smallest ack.";
- } else if (i < kPacketHeaderSize + 30) {
+ } else if (i < 30) {
expected_error = "Unable to read time received.";
- } else if (i < kPacketHeaderSize + 32) {
+ } else if (i < 32) {
expected_error = "Unable to read sequence delta in acked packets.";
- } else if (i < kPacketHeaderSize + 36) {
+ } else if (i < 36) {
expected_error = "Unable to read time delta in acked packets.";
- } else if (i < kPacketHeaderSize + 38) {
+ } else if (i < 38) {
expected_error = "Unable to read sequence delta in acked packets.";
- } else if (i < kPacketHeaderSize + 42) {
+ } else if (i < 42) {
expected_error = "Unable to read time delta in acked packets.";
- } else if (i < kPacketHeaderSize + 48) {
+ } else if (i < 48) {
expected_error = "Unable to read least unacked.";
- } else if (i < kPacketHeaderSize + 49) {
- expected_error = "Unable to read congestion info type.";
}
- CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_FRAME_DATA);
+ CheckProcessingFails(packet, i + kPacketHeaderSize, expected_error,
+ QUIC_INVALID_FRAME_DATA);
}
}
-TEST_F(QuicFramerTest, AckFrameTCP) {
+TEST_F(QuicFramerTest, CongestionFeedbackFrameTCP) {
unsigned char packet[] = {
// guid
0x10, 0x32, 0x54, 0x76,
@@ -656,40 +658,13 @@ TEST_F(QuicFramerTest, AckFrameTCP) {
// frame count
0x01,
- // frame type (ack frame)
- 0x02,
- // largest received packet sequence number
- 0xBF, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_unacked_packets
- 0x01,
- // missing packet
- 0xBE, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_acked_packets
+ // frame type (congestion feedback frame)
0x03,
- // smallest ack sequence number
- 0xBA, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // ack time
- 0x87, 0x96, 0xA5, 0xB4,
- 0xC3, 0xD2, 0xE1, 0x07,
- // sequence delta
- 0x01, 0x00,
- // time delta
- 0x01, 0x00, 0x00, 0x00,
- // sequence delta (skip one packet)
- 0x03, 0x00,
- // time delta
- 0x02, 0x00, 0x00, 0x00,
- // least packet sequence number awaiting an ack
- 0xA0, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
// congestion feedback type (tcp)
- 0x01,
- // ack_frame.congestion_info.tcp.accumulated_number_of_lost_packets
+ 0x00,
+ // ack_frame.feedback.tcp.accumulated_number_of_lost_packets
0x01, 0x02,
- // ack_frame.congestion_info.tcp.receive_window
+ // ack_frame.feedback.tcp.receive_window
0x03, 0x04,
};
@@ -701,49 +676,34 @@ TEST_F(QuicFramerTest, AckFrameTCP) {
ASSERT_TRUE(visitor_.header_.get());
EXPECT_EQ(0u, visitor_.stream_frames_.size());
- ASSERT_EQ(1u, visitor_.ack_frames_.size());
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.received_info.largest_received);
- ASSERT_EQ(1u, frame.received_info.missing_packets.size());
- SequenceSet::const_iterator missing_iter =
- frame.received_info.missing_packets.begin();
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
- ASSERT_EQ(3u, frame.received_info.received_packet_times.size());
- TimeMap::const_iterator iter =
- frame.received_info.received_packet_times.begin();
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABA), iter->first);
- EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687)),
- iter->second);
- ++iter;
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABB), iter->first);
- EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59688)),
- iter->second);
- ++iter;
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABD), iter->first);
- EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59689)),
- iter->second);
-
- EXPECT_EQ(GG_UINT64_C(0x0123456789AA0), frame.sent_info.least_unacked);
- ASSERT_EQ(kTCP, frame.congestion_info.type);
+ ASSERT_EQ(1u, visitor_.congestion_feedback_frames_.size());
+ const QuicCongestionFeedbackFrame& frame =
+ *visitor_.congestion_feedback_frames_[0];
+ ASSERT_EQ(kTCP, frame.type);
EXPECT_EQ(0x0201,
- frame.congestion_info.tcp.accumulated_number_of_lost_packets);
- EXPECT_EQ(0x0403, frame.congestion_info.tcp.receive_window);
+ frame.tcp.accumulated_number_of_lost_packets);
+ EXPECT_EQ(0x0403, frame.tcp.receive_window);
// Now test framing boundaries
- for (size_t i = kCongestionInfoOffset; i < kCongestionInfoOffset + 5; ++i) {
+ for (size_t i = 0; i < 7; ++i) {
string expected_error;
- if (i < kCongestionInfoOffset + 1) {
- expected_error = "Unable to read congestion info type.";
- } else if (i < kCongestionInfoOffset + 3) {
+ if (i < 1) {
+ expected_error = "Unable to read frame count.";
+ } else if (i < 2) {
+ expected_error = "Unable to read frame type.";
+ } else if (i < 3) {
+ expected_error = "Unable to read congestion feedback type.";
+ } else if (i < 5) {
expected_error = "Unable to read accumulated number of lost packets.";
- } else if (i < kCongestionInfoOffset + 5) {
+ } else if (i < 7) {
expected_error = "Unable to read receive window.";
}
- CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_FRAME_DATA);
+ CheckProcessingFails(packet, i + kPacketHeaderSize, expected_error,
+ QUIC_INVALID_FRAME_DATA);
}
}
-TEST_F(QuicFramerTest, AckFrameInterArrival) {
+TEST_F(QuicFramerTest, CongestionFeedbackFrameInterArrival) {
unsigned char packet[] = {
// guid
0x10, 0x32, 0x54, 0x76,
@@ -758,37 +718,10 @@ TEST_F(QuicFramerTest, AckFrameInterArrival) {
// frame count
0x01,
- // frame type (ack frame)
- 0x02,
- // largest received packet sequence number
- 0xBF, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_unacked_packets
- 0x01,
- // missing packet
- 0xBE, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_acked_packets
+ // frame type (congestion feedback frame)
0x03,
- // smallest ack sequence number
- 0xBA, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // ack time
- 0x87, 0x96, 0xA5, 0xB4,
- 0xC3, 0xD2, 0xE1, 0x07,
- // sequence delta
- 0x01, 0x00,
- // time delta
- 0x01, 0x00, 0x00, 0x00,
- // sequence delta (skip one packet)
- 0x03, 0x00,
- // time delta
- 0x02, 0x00, 0x00, 0x00,
- // least packet sequence number awaiting an ack
- 0xA0, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
// congestion feedback type (inter arrival)
- 0x02,
+ 0x01,
// accumulated_number_of_lost_packets
0x02, 0x03,
// offset_time
@@ -805,53 +738,37 @@ TEST_F(QuicFramerTest, AckFrameInterArrival) {
ASSERT_TRUE(visitor_.header_.get());
EXPECT_EQ(0u, visitor_.stream_frames_.size());
- ASSERT_EQ(1u, visitor_.ack_frames_.size());
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.received_info.largest_received);
- ASSERT_EQ(1u, frame.received_info.missing_packets.size());
- SequenceSet::const_iterator missing_iter =
- frame.received_info.missing_packets.begin();
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
- ASSERT_EQ(3u, frame.received_info.received_packet_times.size());
- TimeMap::const_iterator iter =
- frame.received_info.received_packet_times.begin();
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABA), iter->first);
- EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687)),
- iter->second);
- ++iter;
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABB), iter->first);
- EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59688)),
- iter->second);
- ++iter;
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABD), iter->first);
- EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59689)),
- iter->second);
-
- EXPECT_EQ(GG_UINT64_C(0x0123456789AA0),
- frame.sent_info.least_unacked);
- ASSERT_EQ(kInterArrival, frame.congestion_info.type);
- EXPECT_EQ(0x0302, frame.congestion_info.inter_arrival.
+ ASSERT_EQ(1u, visitor_.congestion_feedback_frames_.size());
+ const QuicCongestionFeedbackFrame& frame =
+ *visitor_.congestion_feedback_frames_[0];
+ ASSERT_EQ(kInterArrival, frame.type);
+ EXPECT_EQ(0x0302, frame.inter_arrival.
accumulated_number_of_lost_packets);
- EXPECT_EQ(0x0504, frame.congestion_info.inter_arrival.offset_time);
- EXPECT_EQ(0x0706, frame.congestion_info.inter_arrival.delta_time);
+ EXPECT_EQ(0x0504, frame.inter_arrival.offset_time);
+ EXPECT_EQ(0x0706, frame.inter_arrival.delta_time);
// Now test framing boundaries
- for (size_t i = kCongestionInfoOffset; i < kCongestionInfoOffset + 5; ++i) {
+ for (size_t i = 0; i < 7; ++i) {
string expected_error;
- if (i < kCongestionInfoOffset + 1) {
- expected_error = "Unable to read congestion info type.";
- } else if (i < kCongestionInfoOffset + 3) {
+ if (i < 1) {
+ expected_error = "Unable to read frame count.";
+ } else if (i < 2) {
+ expected_error = "Unable to read frame type.";
+ } else if (i < 3) {
+ expected_error = "Unable to read congestion feedback type.";
+ } else if (i < 5) {
expected_error = "Unable to read accumulated number of lost packets.";
- } else if (i < kCongestionInfoOffset + 5) {
+ } else if (i < 7) {
expected_error = "Unable to read offset time.";
- } else if (i < kCongestionInfoOffset + 7) {
+ } else if (i < 9) {
expected_error = "Unable to read delta time.";
}
- CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_FRAME_DATA);
+ CheckProcessingFails(packet, i + kPacketHeaderSize, expected_error,
+ QUIC_INVALID_FRAME_DATA);
}
}
-TEST_F(QuicFramerTest, AckFrameFixRate) {
+TEST_F(QuicFramerTest, CongestionFeedbackFrameFixRate) {
unsigned char packet[] = {
// guid
0x10, 0x32, 0x54, 0x76,
@@ -866,37 +783,10 @@ TEST_F(QuicFramerTest, AckFrameFixRate) {
// frame count
0x01,
- // frame type (ack frame)
- 0x02,
- // largest received packet sequence number
- 0xBF, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_unacked_packets
- 0x01,
- // missing packet
- 0xBE, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_acked_packets
+ // frame type (congestion feedback frame)
0x03,
- // smallest ack sequence number
- 0xBA, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // ack time
- 0x87, 0x96, 0xA5, 0xB4,
- 0xC3, 0xD2, 0xE1, 0x07,
- // sequence delta
- 0x01, 0x00,
- // time delta
- 0x01, 0x00, 0x00, 0x00,
- // sequence delta (skip one packet)
- 0x03, 0x00,
- // time delta
- 0x02, 0x00, 0x00, 0x00,
- // least packet sequence number awaiting an ack
- 0xA0, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
// congestion feedback type (fix rate)
- 0x03,
+ 0x02,
// bitrate_in_bytes_per_second;
0x01, 0x02, 0x03, 0x04,
};
@@ -909,47 +799,32 @@ TEST_F(QuicFramerTest, AckFrameFixRate) {
ASSERT_TRUE(visitor_.header_.get());
EXPECT_EQ(0u, visitor_.stream_frames_.size());
- ASSERT_EQ(1u, visitor_.ack_frames_.size());
- const QuicAckFrame& frame = *visitor_.ack_frames_[0];
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABF), frame.received_info.largest_received);
- ASSERT_EQ(1u, frame.received_info.missing_packets.size());
- SequenceSet::const_iterator missing_iter =
- frame.received_info.missing_packets.begin();
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABE), *missing_iter);
- ASSERT_EQ(3u, frame.received_info.received_packet_times.size());
- TimeMap::const_iterator iter =
- frame.received_info.received_packet_times.begin();
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABA), iter->first);
- EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687)),
- iter->second);
- ++iter;
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABB), iter->first);
- EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59688)),
- iter->second);
- ++iter;
- EXPECT_EQ(GG_UINT64_C(0x0123456789ABD), iter->first);
- EXPECT_EQ(QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59689)),
- iter->second);
- EXPECT_EQ(GG_UINT64_C(0x0123456789AA0),
- frame.sent_info.least_unacked);
- ASSERT_EQ(kFixRate, frame.congestion_info.type);
+ ASSERT_EQ(1u, visitor_.congestion_feedback_frames_.size());
+ const QuicCongestionFeedbackFrame& frame =
+ *visitor_.congestion_feedback_frames_[0];
+ ASSERT_EQ(kFixRate, frame.type);
EXPECT_EQ(static_cast<uint32>(0x04030201),
- frame.congestion_info.fix_rate.bitrate_in_bytes_per_second);
+ frame.fix_rate.bitrate_in_bytes_per_second);
// Now test framing boundaries
- for (size_t i = kCongestionInfoOffset; i < kCongestionInfoOffset + 5; ++i) {
+ for (size_t i = 0; i < 7; ++i) {
string expected_error;
- if (i < kCongestionInfoOffset + 1) {
- expected_error = "Unable to read congestion info type.";
- } else if (i < kCongestionInfoOffset + 5) {
+ if (i < 1) {
+ expected_error = "Unable to read frame count.";
+ } else if (i < 2) {
+ expected_error = "Unable to read frame type.";
+ } else if (i < 3) {
+ expected_error = "Unable to read congestion feedback type.";
+ } else if (i < 7) {
expected_error = "Unable to read bitrate.";
}
- CheckProcessingFails(packet, i, expected_error, QUIC_INVALID_FRAME_DATA);
+ CheckProcessingFails(packet, i + kPacketHeaderSize, expected_error,
+ QUIC_INVALID_FRAME_DATA);
}
}
-TEST_F(QuicFramerTest, AckFrameInvalidFeedback) {
+TEST_F(QuicFramerTest, CongestionFeedbackFrameInvalidFeedback) {
unsigned char packet[] = {
// guid
0x10, 0x32, 0x54, 0x76,
@@ -964,37 +839,10 @@ TEST_F(QuicFramerTest, AckFrameInvalidFeedback) {
// frame count
0x01,
- // frame type (ack frame)
- 0x02,
- // largest received packet sequence number
- 0xBF, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_unacked_packets
- 0x01,
- // missing packet
- 0xBE, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_acked_packets
+ // frame type (congestion feedback frame)
0x03,
- // smallest ack sequence number
- 0xBA, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // ack time
- 0x87, 0x96, 0xA5, 0xB4,
- 0xC3, 0xD2, 0xE1, 0x07,
- // sequence delta
- 0x01, 0x00,
- // time delta
- 0x01, 0x00, 0x00, 0x00,
- // sequence delta (skip one packet)
- 0x03, 0x00,
- // time delta
- 0x02, 0x00, 0x00, 0x00,
- // least packet sequence number awaiting an ack
- 0xA0, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
// congestion feedback type (invalid)
- 0x04,
+ 0x03,
};
QuicEncryptedPacket encrypted(AsChars(packet), arraysize(packet), false);
@@ -1019,7 +867,7 @@ TEST_F(QuicFramerTest, RstStreamFrame) {
// frame count
0x01,
// frame type (rst stream frame)
- 0x03,
+ 0x04,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
@@ -1052,18 +900,18 @@ TEST_F(QuicFramerTest, RstStreamFrame) {
EXPECT_EQ("because I can", visitor_.rst_stream_frame_.error_details);
// Now test framing boundaries
- for (size_t i = kPacketHeaderSize + 3; i < kPacketHeaderSize + 33; ++i) {
+ for (size_t i = 3; i < 33; ++i) {
string expected_error;
- if (i < kPacketHeaderSize + 6) {
+ if (i < 6) {
expected_error = "Unable to read stream_id.";
- } else if (i < kPacketHeaderSize + 14) {
+ } else if (i < 14) {
expected_error = "Unable to read offset in rst frame.";
- } else if (i < kPacketHeaderSize + 18) {
+ } else if (i < 18) {
expected_error = "Unable to read rst stream error code.";
- } else if (i < kPacketHeaderSize + 33) {
+ } else if (i < 33) {
expected_error = "Unable to read rst stream error details.";
}
- CheckProcessingFails(packet, i, expected_error,
+ CheckProcessingFails(packet, i + kPacketHeaderSize, expected_error,
QUIC_INVALID_RST_STREAM_DATA);
}
}
@@ -1085,7 +933,7 @@ TEST_F(QuicFramerTest, ConnectionCloseFrame) {
// frame count
0x01,
// frame type (connection close frame)
- 0x04,
+ 0x05,
// error code
0x08, 0x07, 0x06, 0x05,
@@ -1170,23 +1018,16 @@ TEST_F(QuicFramerTest, ConnectionCloseFrame) {
iter->second);
EXPECT_EQ(GG_UINT64_C(0x0123456789AA0),
frame.sent_info.least_unacked);
- ASSERT_EQ(kInterArrival, frame.congestion_info.type);
- EXPECT_EQ(0x0302, frame.congestion_info.inter_arrival.
- accumulated_number_of_lost_packets);
- EXPECT_EQ(0x0504,
- frame.congestion_info.inter_arrival.offset_time);
- EXPECT_EQ(0x0706,
- frame.congestion_info.inter_arrival.delta_time);
// Now test framing boundaries
- for (size_t i = kPacketHeaderSize + 3; i < kPacketHeaderSize + 21; ++i) {
+ for (size_t i = 3; i < 21; ++i) {
string expected_error;
- if (i < kPacketHeaderSize + 6) {
+ if (i < 6) {
expected_error = "Unable to read connection close error code.";
- } else if (i < kPacketHeaderSize + 21) {
+ } else if (i < 21) {
expected_error = "Unable to read connection close error details.";
}
- CheckProcessingFails(packet, i, expected_error,
+ CheckProcessingFails(packet, i + kPacketHeaderSize, expected_error,
QUIC_INVALID_CONNECTION_CLOSE_DATA);
}
}
@@ -1243,12 +1084,8 @@ TEST_F(QuicFramerTest, ConstructStreamFramePacket) {
stream_frame.offset = GG_UINT64_C(0xBA98FEDC32107654);
stream_frame.data = "hello world!";
- QuicFrame frame;
- frame.type = STREAM_FRAME;
- frame.stream_frame = &stream_frame;
-
QuicFrames frames;
- frames.push_back(frame);
+ frames.push_back(QuicFrame(&stream_frame));
unsigned char packet[] = {
// guid
@@ -1308,14 +1145,9 @@ TEST_F(QuicFramerTest, ConstructAckFramePacket) {
ack_frame.received_info.received_packet_times[GG_UINT64_C(0x0123456789ABD)] =
QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59689));
ack_frame.sent_info.least_unacked = GG_UINT64_C(0x0123456789AA0);
- ack_frame.congestion_info.type = kNone;
-
- QuicFrame frame;
- frame.type = ACK_FRAME;
- frame.ack_frame = &ack_frame;
QuicFrames frames;
- frames.push_back(frame);
+ frames.push_back(QuicFrame(&ack_frame));
unsigned char packet[] = {
// guid
@@ -1360,12 +1192,10 @@ TEST_F(QuicFramerTest, ConstructAckFramePacket) {
// least packet sequence number awaiting an ack
0xA0, 0x9A, 0x78, 0x56,
0x34, 0x12,
- // congestion feedback type (none)
- 0x00,
};
QuicPacket* data;
- EXPECT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data));
+ ASSERT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data));
test::CompareCharArraysWithHexError("constructed packet",
data->data(), data->length(),
@@ -1374,33 +1204,20 @@ TEST_F(QuicFramerTest, ConstructAckFramePacket) {
delete data;
}
-TEST_F(QuicFramerTest, ConstructAckFramePacketTCP) {
+TEST_F(QuicFramerTest, ConstructCongestionFeedbackFramePacketTCP) {
QuicPacketHeader header;
header.guid = GG_UINT64_C(0xFEDCBA9876543210);
header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
header.flags = PACKET_FLAGS_NONE;
header.fec_group = 0;
- QuicAckFrame ack_frame;
- ack_frame.received_info.largest_received = GG_UINT64_C(0x0123456789ABF);
- ack_frame.received_info.missing_packets.insert(GG_UINT64_C(0x0123456789ABE));
- ack_frame.received_info.received_packet_times[GG_UINT64_C(0x0123456789ABA)] =
- QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687));
- ack_frame.received_info.received_packet_times[GG_UINT64_C(0x0123456789ABB)] =
- QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59688));
- ack_frame.received_info.received_packet_times[GG_UINT64_C(0x0123456789ABD)] =
- QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59689));
- ack_frame.sent_info.least_unacked = GG_UINT64_C(0x0123456789AA0);
- ack_frame.congestion_info.type = kTCP;
- ack_frame.congestion_info.tcp.accumulated_number_of_lost_packets = 0x0201;
- ack_frame.congestion_info.tcp.receive_window = 0x0403;
-
- QuicFrame frame;
- frame.type = ACK_FRAME;
- frame.ack_frame = &ack_frame;
+ QuicCongestionFeedbackFrame congestion_feedback_frame;
+ congestion_feedback_frame.type = kTCP;
+ congestion_feedback_frame.tcp.accumulated_number_of_lost_packets = 0x0201;
+ congestion_feedback_frame.tcp.receive_window = 0x0403;
QuicFrames frames;
- frames.push_back(frame);
+ frames.push_back(QuicFrame(&congestion_feedback_frame));
unsigned char packet[] = {
// guid
@@ -1416,45 +1233,18 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketTCP) {
// frame count
0x01,
- // frame type (ack frame)
- 0x02,
- // largest received packet sequence number
- 0xBF, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_unacked_packets
- 0x01,
- // missing packet
- 0xBE, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_acked_packets
+ // frame type (congestion feedback frame)
0x03,
- // smallest ack sequence number
- 0xBA, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // ack time
- 0x87, 0x96, 0xA5, 0xB4,
- 0xC3, 0xD2, 0xE1, 0x07,
- // sequence delta
- 0x01, 0x00,
- // time delta
- 0x01, 0x00, 0x00, 0x00,
- // sequence delta (skip one packet)
- 0x03, 0x00,
- // time delta
- 0x02, 0x00, 0x00, 0x00,
- // least packet sequence number awaiting an ack
- 0xA0, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // congestion feedback type (tcp)
- 0x01,
- // ack_frame.congestion_info.tcp.accumulated_number_of_lost_packets
+ // congestion feedback type (TCP)
+ 0x00,
+ // accumulated number of lost packets
0x01, 0x02,
- // ack_frame.congestion_info.tcp.receive_window
+ // TCP receive window
0x03, 0x04,
};
QuicPacket* data;
- EXPECT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data));
+ ASSERT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data));
test::CompareCharArraysWithHexError("constructed packet",
data->data(), data->length(),
@@ -1463,35 +1253,22 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketTCP) {
delete data;
}
-TEST_F(QuicFramerTest, ConstructAckFramePacketInterArrival) {
+TEST_F(QuicFramerTest, ConstructCongestionFeedbackFramePacketInterArrival) {
QuicPacketHeader header;
header.guid = GG_UINT64_C(0xFEDCBA9876543210);
header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
header.flags = PACKET_FLAGS_NONE;
header.fec_group = 0;
- QuicAckFrame ack_frame;
- ack_frame.received_info.largest_received = GG_UINT64_C(0x0123456789ABF);
- ack_frame.received_info.missing_packets.insert(GG_UINT64_C(0x0123456789ABE));
- ack_frame.received_info.received_packet_times[GG_UINT64_C(0x0123456789ABA)] =
- QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687));
- ack_frame.received_info.received_packet_times[GG_UINT64_C(0x0123456789ABB)] =
- QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59688));
- ack_frame.received_info.received_packet_times[GG_UINT64_C(0x0123456789ABD)] =
- QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59689));
- ack_frame.sent_info.least_unacked = GG_UINT64_C(0x0123456789AA0);
- ack_frame.congestion_info.type = kInterArrival;
- ack_frame.congestion_info.inter_arrival.accumulated_number_of_lost_packets
+ QuicCongestionFeedbackFrame congestion_feedback_frame;
+ congestion_feedback_frame.type = kInterArrival;
+ congestion_feedback_frame.inter_arrival.accumulated_number_of_lost_packets
= 0x0302;
- ack_frame.congestion_info.inter_arrival.offset_time = 0x0504;
- ack_frame.congestion_info.inter_arrival.delta_time = 0x0706;
-
- QuicFrame frame;
- frame.type = ACK_FRAME;
- frame.ack_frame = &ack_frame;
+ congestion_feedback_frame.inter_arrival.offset_time = 0x0504;
+ congestion_feedback_frame.inter_arrival.delta_time = 0x0706;
QuicFrames frames;
- frames.push_back(frame);
+ frames.push_back(QuicFrame(&congestion_feedback_frame));
unsigned char packet[] = {
// guid
@@ -1507,37 +1284,10 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketInterArrival) {
// frame count
0x01,
- // frame type (ack frame)
- 0x02,
- // largest received packet sequence number
- 0xBF, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_unacked_packets
- 0x01,
- // missing packet
- 0xBE, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_acked_packets
+ // frame type (congestion feedback frame)
0x03,
- // smallest ack sequence number
- 0xBA, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // ack time
- 0x87, 0x96, 0xA5, 0xB4,
- 0xC3, 0xD2, 0xE1, 0x07,
- // sequence delta
- 0x01, 0x00,
- // time delta
- 0x01, 0x00, 0x00, 0x00,
- // sequence delta (skip one packet)
- 0x03, 0x00,
- // time delta
- 0x02, 0x00, 0x00, 0x00,
- // least packet sequence number awaiting an ack
- 0xA0, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
// congestion feedback type (inter arrival)
- 0x02,
+ 0x01,
// accumulated_number_of_lost_packets
0x02, 0x03,
// offset_time
@@ -1547,7 +1297,7 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketInterArrival) {
};
QuicPacket* data;
- EXPECT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data));
+ ASSERT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data));
test::CompareCharArraysWithHexError("constructed packet",
data->data(), data->length(),
@@ -1556,33 +1306,20 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketInterArrival) {
delete data;
}
-TEST_F(QuicFramerTest, ConstructAckFramePacketFixRate) {
+TEST_F(QuicFramerTest, ConstructCongestionFeedbackFramePacketFixRate) {
QuicPacketHeader header;
header.guid = GG_UINT64_C(0xFEDCBA9876543210);
header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
header.flags = PACKET_FLAGS_NONE;
header.fec_group = 0;
- QuicAckFrame ack_frame;
- ack_frame.received_info.largest_received = GG_UINT64_C(0x0123456789ABF);
- ack_frame.received_info.missing_packets.insert(GG_UINT64_C(0x0123456789ABE));
- ack_frame.received_info.received_packet_times[GG_UINT64_C(0x0123456789ABA)] =
- QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687));
- ack_frame.received_info.received_packet_times[GG_UINT64_C(0x0123456789ABB)] =
- QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59688));
- ack_frame.received_info.received_packet_times[GG_UINT64_C(0x0123456789ABD)] =
- QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59689));
- ack_frame.sent_info.least_unacked = GG_UINT64_C(0x0123456789AA0);
- ack_frame.congestion_info.type = kFixRate;
- ack_frame.congestion_info.fix_rate.bitrate_in_bytes_per_second
+ QuicCongestionFeedbackFrame congestion_feedback_frame;
+ congestion_feedback_frame.type = kFixRate;
+ congestion_feedback_frame.fix_rate.bitrate_in_bytes_per_second
= 0x04030201;
- QuicFrame frame;
- frame.type = ACK_FRAME;
- frame.ack_frame = &ack_frame;
-
QuicFrames frames;
- frames.push_back(frame);
+ frames.push_back(QuicFrame(&congestion_feedback_frame));
unsigned char packet[] = {
// guid
@@ -1598,43 +1335,16 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketFixRate) {
// frame count
0x01,
- // frame type (ack frame)
- 0x02,
- // largest received packet sequence number
- 0xBF, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_unacked_packets
- 0x01,
- // missing packet
- 0xBE, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // num_acked_packets
+ // frame type (congestion feedback frame)
0x03,
- // smallest ack sequence number
- 0xBA, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
- // ack time
- 0x87, 0x96, 0xA5, 0xB4,
- 0xC3, 0xD2, 0xE1, 0x07,
- // sequence delta
- 0x01, 0x00,
- // time delta
- 0x01, 0x00, 0x00, 0x00,
- // sequence delta (skip one packet)
- 0x03, 0x00,
- // time delta
- 0x02, 0x00, 0x00, 0x00,
- // least packet sequence number awaiting an ack
- 0xA0, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
// congestion feedback type (fix rate)
- 0x03,
+ 0x02,
// bitrate_in_bytes_per_second;
0x01, 0x02, 0x03, 0x04,
};
QuicPacket* data;
- EXPECT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data));
+ ASSERT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data));
test::CompareCharArraysWithHexError("constructed packet",
data->data(), data->length(),
@@ -1643,32 +1353,19 @@ TEST_F(QuicFramerTest, ConstructAckFramePacketFixRate) {
delete data;
}
-TEST_F(QuicFramerTest, ConstructAckFramePacketInvalidFeedback) {
+TEST_F(QuicFramerTest, ConstructCongestionFeedbackFramePacketInvalidFeedback) {
QuicPacketHeader header;
header.guid = GG_UINT64_C(0xFEDCBA9876543210);
header.packet_sequence_number = GG_UINT64_C(0x123456789ABC);
header.flags = PACKET_FLAGS_NONE;
header.fec_group = 0;
- QuicAckFrame ack_frame;
- ack_frame.received_info.largest_received = GG_UINT64_C(0x0123456789ABF);
- ack_frame.received_info.missing_packets.insert(GG_UINT64_C(0x0123456789ABE));
- ack_frame.received_info.received_packet_times[GG_UINT64_C(0x0123456789ABA)] =
- QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59687));
- ack_frame.received_info.received_packet_times[GG_UINT64_C(0x0123456789ABB)] =
- QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59688));
- ack_frame.received_info.received_packet_times[GG_UINT64_C(0x0123456789ABD)] =
- QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59689));
- ack_frame.sent_info.least_unacked = GG_UINT64_C(0x0123456789AA0);
- ack_frame.congestion_info.type =
+ QuicCongestionFeedbackFrame congestion_feedback_frame;
+ congestion_feedback_frame.type =
static_cast<CongestionFeedbackType>(kFixRate + 1);
- QuicFrame frame;
- frame.type = ACK_FRAME;
- frame.ack_frame = &ack_frame;
-
QuicFrames frames;
- frames.push_back(frame);
+ frames.push_back(QuicFrame(&congestion_feedback_frame));
QuicPacket* data;
EXPECT_FALSE(framer_.ConstructFrameDataPacket(header, frames, &data));
@@ -1702,7 +1399,7 @@ TEST_F(QuicFramerTest, ConstructRstFramePacket) {
// frame count
0x01,
// frame type (rst stream frame)
- 0x03,
+ 0x04,
// stream id
0x04, 0x03, 0x02, 0x01,
// offset
@@ -1719,13 +1416,11 @@ TEST_F(QuicFramerTest, ConstructRstFramePacket) {
'n',
};
- QuicFrame frame(&rst_frame);
-
QuicFrames frames;
- frames.push_back(frame);
+ frames.push_back(QuicFrame(&rst_frame));
QuicPacket* data;
- EXPECT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data));
+ ASSERT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data));
test::CompareCharArraysWithHexError("constructed packet",
data->data(), data->length(),
@@ -1755,16 +1450,9 @@ TEST_F(QuicFramerTest, ConstructCloseFramePacket) {
ack_frame->received_info.received_packet_times[GG_UINT64_C(0x0123456789ABD)] =
QuicTime::FromMicroseconds(GG_UINT64_C(0x07E1D2C3B4A59689));
ack_frame->sent_info.least_unacked = GG_UINT64_C(0x0123456789AA0);
- ack_frame->congestion_info.type = kInterArrival;
- ack_frame->congestion_info.inter_arrival.accumulated_number_of_lost_packets
- = 0x0302;
- ack_frame->congestion_info.inter_arrival.offset_time = 0x0504;
- ack_frame->congestion_info.inter_arrival.delta_time = 0x0706;
-
- QuicFrame frame(&close_frame);
QuicFrames frames;
- frames.push_back(frame);
+ frames.push_back(QuicFrame(&close_frame));
unsigned char packet[] = {
// guid
@@ -1781,7 +1469,7 @@ TEST_F(QuicFramerTest, ConstructCloseFramePacket) {
// frame count
0x01,
// frame type (connection close frame)
- 0x04,
+ 0x05,
// error code
0x08, 0x07, 0x06, 0x05,
// error details length
@@ -1821,18 +1509,10 @@ TEST_F(QuicFramerTest, ConstructCloseFramePacket) {
// least packet sequence number awaiting an ack
0xA0, 0x9A, 0x78, 0x56,
0x34, 0x12,
- // congestion feedback type (inter arrival)
- 0x02,
- // accumulated_number_of_lost_packets
- 0x02, 0x03,
- // offset_time
- 0x04, 0x05,
- // delta_time
- 0x06, 0x07,
};
QuicPacket* data;
- EXPECT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data));
+ ASSERT_TRUE(framer_.ConstructFrameDataPacket(header, frames, &data));
test::CompareCharArraysWithHexError("constructed packet",
data->data(), data->length(),
@@ -1876,7 +1556,7 @@ TEST_F(QuicFramerTest, ConstructFecPacket) {
};
QuicPacket* data;
- EXPECT_TRUE(framer_.ConstructFecPacket(header, fec_data, &data));
+ ASSERT_TRUE(framer_.ConstructFecPacket(header, fec_data, &data));
test::CompareCharArraysWithHexError("constructed packet",
data->data(), data->length(),
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc
index 8864224..53ed8eb 100644
--- a/net/quic/quic_http_stream_test.cc
+++ b/net/quic/quic_http_stream_test.cc
@@ -31,6 +31,11 @@ class QuicConnectionPeer {
QuicSendScheduler* scheduler) {
connection->scheduler_.reset(scheduler);
}
+
+ static void SetCollector(QuicConnection* connection,
+ QuicReceiptMetricsCollector* collector) {
+ connection->collector_.reset(collector);
+ }
};
namespace test {
@@ -50,6 +55,36 @@ class TestQuicConnection : public QuicConnection {
void SetScheduler(QuicSendScheduler* scheduler) {
QuicConnectionPeer::SetScheduler(this, scheduler);
}
+
+ void SetCollector(QuicReceiptMetricsCollector* collector) {
+ QuicConnectionPeer::SetCollector(this, collector);
+ }
+};
+
+class TestCollector : public QuicReceiptMetricsCollector {
+ public:
+ explicit TestCollector(QuicCongestionFeedbackFrame* feedback)
+ : QuicReceiptMetricsCollector(&clock_, kFixRate),
+ feedback_(feedback) {
+ }
+
+ bool GenerateCongestionFeedback(
+ QuicCongestionFeedbackFrame* congestion_feedback) {
+ if (feedback_ == NULL) {
+ return false;
+ }
+ *congestion_feedback = *feedback_;
+ return true;
+ }
+
+ MOCK_METHOD4(RecordIncomingPacket,
+ void(size_t, QuicPacketSequenceNumber, QuicTime, bool));
+
+ private:
+ MockClock clock_;
+ QuicCongestionFeedbackFrame* feedback_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestCollector);
};
} // namespace
@@ -124,12 +159,14 @@ class QuicHttpStreamTest : public ::testing::Test {
socket->Connect(peer_addr_);
runner_ = new TestTaskRunner(&clock_);
scheduler_ = new MockScheduler();
+ collector_ = new TestCollector(NULL);
EXPECT_CALL(*scheduler_, TimeUntilSend(_)).
WillRepeatedly(testing::Return(QuicTime::Delta()));
helper_ = new QuicConnectionHelper(runner_.get(), &clock_, socket);
connection_ = new TestQuicConnection(guid_, peer_addr_, helper_);
connection_->set_visitor(&visitor_);
connection_->SetScheduler(scheduler_);
+ connection_->SetCollector(collector_);
session_.reset(new QuicClientSession(connection_, helper_, NULL));
CryptoHandshakeMessage message;
message.tag = kSHLO;
@@ -156,9 +193,6 @@ class QuicHttpStreamTest : public ::testing::Test {
InitializeHeader(sequence_number);
QuicAckFrame ack(largest_received, QuicTime(), sequence_number);
- ack.congestion_info.type = kTCP;
- ack.congestion_info.tcp.accumulated_number_of_lost_packets = 0;
- ack.congestion_info.tcp.receive_window = 16000;
// TODO(rch): remove this grotty hack once we move the packet times
// out of the ack frame.
if (sequence_number == 4) {
@@ -169,30 +203,9 @@ class QuicHttpStreamTest : public ::testing::Test {
return ConstructPacket(header_, QuicFrame(&ack));
}
- // Returns a newly created packet to send a connection close frame.
- QuicEncryptedPacket* ConstructClosePacket(
- QuicPacketSequenceNumber sequence_number,
- bool with_congestion_info) {
- InitializeHeader(sequence_number);
-
- QuicFrames frames;
- QuicAckFrame ack(0, QuicTime(), 0);
- if (with_congestion_info) {
- ack.congestion_info.type = kTCP;
- ack.congestion_info.tcp.accumulated_number_of_lost_packets = 0;
- ack.congestion_info.tcp.receive_window = 16000;
- } else {
- ack.congestion_info.type = kNone;
- }
- QuicConnectionCloseFrame close;
- close.error_code = QUIC_CONNECTION_TIMED_OUT;
- close.ack_frame = ack;
-
- return ConstructPacket(header_, QuicFrame(&close));
- }
-
BoundNetLog net_log_;
MockScheduler* scheduler_;
+ TestCollector* collector_;
scoped_refptr<TestTaskRunner> runner_;
scoped_array<MockWrite> mock_writes_;
MockClock clock_;
diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc
index 2f80d29..cbca68a 100644
--- a/net/quic/quic_packet_creator.cc
+++ b/net/quic/quic_packet_creator.cc
@@ -180,6 +180,19 @@ QuicPacketCreator::PacketPair QuicPacketCreator::AckPacket(
return make_pair(header.packet_sequence_number, packet);
}
+QuicPacketCreator::PacketPair QuicPacketCreator::CongestionFeedbackPacket(
+ QuicCongestionFeedbackFrame* feedback_frame) {
+
+ QuicPacketHeader header;
+ FillPacketHeader(0, PACKET_FLAGS_NONE, &header);
+
+ QuicPacket* packet;
+ QuicFrames frames;
+ frames.push_back(QuicFrame(feedback_frame));
+ framer_->ConstructFrameDataPacket(header, frames, &packet);
+ return make_pair(header.packet_sequence_number, packet);
+}
+
QuicPacketSequenceNumber QuicPacketCreator::SetNewSequenceNumber(
QuicPacket* packet) {
++sequence_number_;
diff --git a/net/quic/quic_packet_creator.h b/net/quic/quic_packet_creator.h
index 0353095..8e57ef8 100644
--- a/net/quic/quic_packet_creator.h
+++ b/net/quic/quic_packet_creator.h
@@ -70,6 +70,8 @@ class NET_EXPORT_PRIVATE QuicPacketCreator : public QuicFecBuilderInterface {
PacketPair AckPacket(QuicAckFrame* ack_frame);
+ PacketPair CongestionFeedbackPacket(QuicCongestionFeedbackFrame* ack_frame);
+
// Increments the current sequence number in QuicPacketCreator and sets it
// into the packet and returns the new sequence number.
QuicPacketSequenceNumber SetNewSequenceNumber(QuicPacket* packet);
diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc
index 08cd49f..48045c3 100644
--- a/net/quic/quic_protocol.cc
+++ b/net/quic/quic_protocol.cc
@@ -91,7 +91,6 @@ QuicAckFrame::QuicAckFrame(QuicPacketSequenceNumber largest_received,
}
received_info.largest_received = largest_received;
sent_info.least_unacked = least_unacked;
- congestion_info.type = kNone;
}
ostream& operator<<(ostream& os, const SentPacketInfo& s) {
@@ -117,11 +116,9 @@ ostream& operator<<(ostream& os, const ReceivedPacketInfo& r) {
return os;
}
-ostream& operator<<(ostream& os, const CongestionInfo& c) {
+ostream& operator<<(ostream& os, const QuicCongestionFeedbackFrame& c) {
os << "type: " << c.type;
switch (c.type) {
- case kNone:
- break;
case kInterArrival: {
const CongestionFeedbackMessageInterArrival& inter_arrival =
c.inter_arrival;
@@ -153,9 +150,8 @@ ostream& operator<<(ostream& os, const CongestionInfo& c) {
ostream& operator<<(ostream& os, const QuicAckFrame& a) {
os << "sent info { " << a.sent_info << " } "
- << "received info { " << a.received_info << " } "
- << "congestion info { " << a.congestion_info << " }\n";
- return os;
+ << "received info { " << a.received_info << " }\n";
+ return os;
}
QuicFecData::QuicFecData() {}
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h
index d63abb2..6f82ff1 100644
--- a/net/quic/quic_protocol.h
+++ b/net/quic/quic_protocol.h
@@ -71,6 +71,7 @@ enum QuicFrameType {
STREAM_FRAME = 0,
PDU_FRAME,
ACK_FRAME,
+ CONGESTION_FEEDBACK_FRAME,
RST_STREAM_FRAME,
CONNECTION_CLOSE_FRAME,
NUM_FRAME_TYPES
@@ -175,8 +176,8 @@ typedef std::map<QuicPacketSequenceNumber, QuicTime> TimeMap;
struct NET_EXPORT_PRIVATE ReceivedPacketInfo {
ReceivedPacketInfo();
~ReceivedPacketInfo();
- friend std::ostream& operator<<(std::ostream& os,
- const ReceivedPacketInfo& s);
+ NET_EXPORT_PRIVATE friend std::ostream& operator<<(
+ std::ostream& os, const ReceivedPacketInfo& s);
// Records a packet receipt.
void RecordReceived(QuicPacketSequenceNumber sequence_number, QuicTime time);
@@ -207,17 +208,32 @@ struct NET_EXPORT_PRIVATE ReceivedPacketInfo {
struct NET_EXPORT_PRIVATE SentPacketInfo {
SentPacketInfo();
~SentPacketInfo();
- friend std::ostream& operator<<(std::ostream& os,
- const SentPacketInfo& s);
+ NET_EXPORT_PRIVATE friend std::ostream& operator<<(
+ std::ostream& os, const SentPacketInfo& s);
+
// The lowest packet we've sent which is unacked, and we expect an ack for.
QuicPacketSequenceNumber least_unacked;
};
+struct NET_EXPORT_PRIVATE 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,
+ QuicTime time_received,
+ QuicPacketSequenceNumber least_unacked);
+
+ NET_EXPORT_PRIVATE friend std::ostream& operator<<(
+ std::ostream& os, const QuicAckFrame& s);
+
+ SentPacketInfo sent_info;
+ ReceivedPacketInfo received_info;
+};
+
// Defines for all types of congestion feedback that will be negotiated in QUIC,
// kTCP MUST be supported by all QUIC implementations to guarentee 100%
// compatibility.
enum CongestionFeedbackType {
- kNone = 0, // No feedback provided
kTCP, // Used to mimic TCP.
kInterArrival, // Use additional inter arrival information.
kFixRate, // Provided for testing.
@@ -255,9 +271,11 @@ struct NET_EXPORT_PRIVATE CongestionFeedbackMessageFixRate {
uint32 bitrate_in_bytes_per_second;
};
-struct NET_EXPORT_PRIVATE CongestionInfo {
+struct NET_EXPORT_PRIVATE QuicCongestionFeedbackFrame {
CongestionFeedbackType type;
- friend std::ostream& operator<<(std::ostream& os, const CongestionInfo& c);
+ NET_EXPORT_PRIVATE friend std::ostream& operator<<(
+ std::ostream& os, const QuicCongestionFeedbackFrame& c);
+
union {
CongestionFeedbackMessageTCP tcp;
CongestionFeedbackMessageInterArrival inter_arrival;
@@ -265,22 +283,6 @@ struct NET_EXPORT_PRIVATE CongestionInfo {
};
};
-struct NET_EXPORT_PRIVATE 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,
- QuicTime time_received,
- QuicPacketSequenceNumber least_unacked);
-
- NET_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
- const QuicAckFrame& s);
-
- SentPacketInfo sent_info;
- ReceivedPacketInfo received_info;
- CongestionInfo congestion_info;
-};
-
struct NET_EXPORT_PRIVATE QuicRstStreamFrame {
QuicRstStreamFrame() {}
QuicRstStreamFrame(QuicStreamId stream_id, uint64 offset,
@@ -309,6 +311,9 @@ struct NET_EXPORT_PRIVATE QuicFrame {
explicit QuicFrame(QuicAckFrame* frame)
: type(ACK_FRAME), ack_frame(frame) {
}
+ explicit QuicFrame(QuicCongestionFeedbackFrame* frame)
+ : type(CONGESTION_FEEDBACK_FRAME), congestion_feedback_frame(frame) {
+ }
explicit QuicFrame(QuicRstStreamFrame* frame)
: type(RST_STREAM_FRAME),
rst_stream_frame(frame) {
@@ -322,6 +327,7 @@ struct NET_EXPORT_PRIVATE QuicFrame {
union {
QuicStreamFrame* stream_frame;
QuicAckFrame* ack_frame;
+ QuicCongestionFeedbackFrame* congestion_feedback_frame;
QuicRstStreamFrame* rst_stream_frame;
QuicConnectionCloseFrame* connection_close_frame;
};
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc
index c1a7b36..68920a2 100644
--- a/net/quic/quic_stream_factory_test.cc
+++ b/net/quic/quic_stream_factory_test.cc
@@ -68,14 +68,29 @@ class QuicStreamFactoryTest : public ::testing::Test {
header.fec_group = 0;
QuicAckFrame ack(largest_received, QuicTime(), least_unacked);
- ack.congestion_info.type = kTCP;
- ack.congestion_info.tcp.accumulated_number_of_lost_packets = 0;
- ack.congestion_info.tcp.receive_window = 16000;
return scoped_ptr<QuicEncryptedPacket>(
ConstructPacket(header, QuicFrame(&ack)));
}
+ // Returns a newly created packet to send congestion feedback data.
+ scoped_ptr<QuicEncryptedPacket> ConstructFeedbackPacket(
+ QuicPacketSequenceNumber sequence_number) {
+ QuicPacketHeader header;
+ header.guid = 0xDEADBEEF;
+ header.packet_sequence_number = sequence_number;
+ header.flags = PACKET_FLAGS_NONE;
+ header.fec_group = 0;
+
+ QuicCongestionFeedbackFrame frame;
+ frame.type = kTCP;
+ frame.tcp.accumulated_number_of_lost_packets = 0;
+ frame.tcp.receive_window = 16000;
+
+ return scoped_ptr<QuicEncryptedPacket>(
+ ConstructPacket(header, QuicFrame(&frame)));
+ }
+
scoped_ptr<QuicEncryptedPacket> ConstructPacket(
const QuicPacketHeader& header,
const QuicFrame& frame) {
@@ -112,12 +127,14 @@ TEST_F(QuicStreamFactoryTest, CreateIfSessionExists) {
TEST_F(QuicStreamFactoryTest, Create) {
scoped_ptr<QuicEncryptedPacket> chlo(ConstructChlo());
scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 1));
- scoped_ptr<QuicEncryptedPacket> rst3(ConstructRstPacket(3, 3));
- scoped_ptr<QuicEncryptedPacket> rst5(ConstructRstPacket(4, 5));
- scoped_ptr<QuicEncryptedPacket> rst7(ConstructRstPacket(5, 7));
+ scoped_ptr<QuicEncryptedPacket> feedback(ConstructFeedbackPacket(3));
+ scoped_ptr<QuicEncryptedPacket> rst3(ConstructRstPacket(4, 3));
+ scoped_ptr<QuicEncryptedPacket> rst5(ConstructRstPacket(5, 5));
+ scoped_ptr<QuicEncryptedPacket> rst7(ConstructRstPacket(6, 7));
MockWrite writes[] = {
MockWrite(SYNCHRONOUS, chlo->data(), chlo->length()),
MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
+ MockWrite(SYNCHRONOUS, feedback->data(), feedback->length()),
MockWrite(SYNCHRONOUS, rst3->data(), rst3->length()),
MockWrite(SYNCHRONOUS, rst5->data(), rst5->length()),
MockWrite(SYNCHRONOUS, rst7->data(), rst7->length()),
@@ -173,11 +190,13 @@ TEST_F(QuicStreamFactoryTest, CreateError) {
TEST_F(QuicStreamFactoryTest, CancelCreate) {
scoped_ptr<QuicEncryptedPacket> chlo(ConstructChlo());
scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 1));
- scoped_ptr<QuicEncryptedPacket> rst3(ConstructRstPacket(3, 3));
+ scoped_ptr<QuicEncryptedPacket> feedback(ConstructFeedbackPacket(3));
+ scoped_ptr<QuicEncryptedPacket> rst3(ConstructRstPacket(4, 3));
MockWrite writes[] = {
MockWrite(SYNCHRONOUS, chlo->data(), chlo->length()),
MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
+ MockWrite(SYNCHRONOUS, feedback->data(), feedback->length()),
MockWrite(SYNCHRONOUS, rst3->data(), rst3->length()),
};
scoped_ptr<QuicEncryptedPacket> shlo(ConstructShlo());
diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc
index 6fc7170..133f6a6 100644
--- a/net/quic/test_tools/quic_test_utils.cc
+++ b/net/quic/test_tools/quic_test_utils.cc
@@ -30,6 +30,9 @@ bool NoOpFramerVisitor::OnPacketHeader(const QuicPacketHeader& header) {
FramerVisitorCapturingAcks::FramerVisitorCapturingAcks() {
}
+FramerVisitorCapturingAcks::~FramerVisitorCapturingAcks() {
+}
+
bool FramerVisitorCapturingAcks::OnPacketHeader(
const QuicPacketHeader& header) {
header_ = header;
@@ -37,7 +40,12 @@ bool FramerVisitorCapturingAcks::OnPacketHeader(
}
void FramerVisitorCapturingAcks::OnAckFrame(const QuicAckFrame& frame) {
- frame_ = frame;
+ ack_.reset(new QuicAckFrame(frame));
+}
+
+void FramerVisitorCapturingAcks::OnCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& frame) {
+ feedback_.reset(new QuicCongestionFeedbackFrame(frame));
}
MockHelper::MockHelper() {
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h
index ca0d8a5..342e0b1 100644
--- a/net/quic/test_tools/quic_test_utils.h
+++ b/net/quic/test_tools/quic_test_utils.h
@@ -45,6 +45,8 @@ class MockFramerVisitor : public QuicFramerVisitorInterface {
MOCK_METHOD1(OnFecProtectedPayload, void(base::StringPiece payload));
MOCK_METHOD1(OnStreamFrame, void(const QuicStreamFrame& frame));
MOCK_METHOD1(OnAckFrame, void(const QuicAckFrame& frame));
+ MOCK_METHOD1(OnCongestionFeedbackFrame,
+ void(const QuicCongestionFeedbackFrame& frame));
MOCK_METHOD1(OnFecData, void(const QuicFecData& fec));
MOCK_METHOD1(OnRstStreamFrame, void(const QuicRstStreamFrame& frame));
MOCK_METHOD1(OnConnectionCloseFrame,
@@ -67,6 +69,8 @@ class NoOpFramerVisitor : public QuicFramerVisitorInterface {
virtual void OnFecProtectedPayload(base::StringPiece payload) OVERRIDE {}
virtual void OnStreamFrame(const QuicStreamFrame& frame) OVERRIDE {}
virtual void OnAckFrame(const QuicAckFrame& frame) OVERRIDE {}
+ virtual void OnCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& frame) OVERRIDE {}
virtual void OnFecData(const QuicFecData& fec) OVERRIDE {}
virtual void OnRstStreamFrame(const QuicRstStreamFrame& frame) OVERRIDE {}
virtual void OnConnectionCloseFrame(
@@ -80,17 +84,23 @@ class NoOpFramerVisitor : public QuicFramerVisitorInterface {
class FramerVisitorCapturingAcks : public NoOpFramerVisitor {
public:
FramerVisitorCapturingAcks();
+ virtual ~FramerVisitorCapturingAcks();
// NoOpFramerVisitor
virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE;
virtual void OnAckFrame(const QuicAckFrame& frame) OVERRIDE;
+ virtual void OnCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& frame) OVERRIDE;
QuicPacketHeader* header() { return &header_; }
- QuicAckFrame* frame() { return &frame_; }
+
+ QuicAckFrame* ack() { return ack_.get(); }
+ QuicCongestionFeedbackFrame* feedback() { return feedback_.get(); }
private:
QuicPacketHeader header_;
- QuicAckFrame frame_;
+ scoped_ptr<QuicAckFrame> ack_;
+ scoped_ptr<QuicCongestionFeedbackFrame> feedback_;
DISALLOW_COPY_AND_ASSIGN(FramerVisitorCapturingAcks);
};