diff options
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); }; |