Add a method that writes AckFrequencyFrame in QuicControlFrameManager and code for updating peer_max_ack_delay in QuicSentPacketManager. PiperOrigin-RevId: 332528530 Change-Id: I3a67955fc6f6f6850da117b878a189a28bf7ee4c
diff --git a/quic/core/quic_control_frame_manager.cc b/quic/core/quic_control_frame_manager.cc index c2fdc38..28b3446 100644 --- a/quic/core/quic_control_frame_manager.cc +++ b/quic/core/quic_control_frame_manager.cc
@@ -6,6 +6,8 @@ #include <string> +#include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h" +#include "net/third_party/quiche/src/quic/core/frames/quic_frame.h" #include "net/third_party/quiche/src/quic/core/quic_constants.h" #include "net/third_party/quiche/src/quic/core/quic_session.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" @@ -117,6 +119,16 @@ QuicFrame(QuicHandshakeDoneFrame(++last_control_frame_id_))); } +void QuicControlFrameManager::WriteOrBufferAckFrequency( + uint64_t packet_tolerance, + QuicTime::Delta max_ack_delay) { + QUIC_DVLOG(1) << "Writing ACK_FREQUENCY frame"; + QuicControlFrameId control_frame_id = ++last_control_frame_id_; + WriteOrBufferQuicFrame(QuicFrame(new QuicAckFrequencyFrame( + control_frame_id, + /*sequence_number=*/control_frame_id, packet_tolerance, max_ack_delay))); +} + void QuicControlFrameManager::WritePing() { QUIC_DVLOG(1) << "Writing PING_FRAME"; if (HasBufferedFrames()) {
diff --git a/quic/core/quic_control_frame_manager.h b/quic/core/quic_control_frame_manager.h index d57d120..d79b679 100644 --- a/quic/core/quic_control_frame_manager.h +++ b/quic/core/quic_control_frame_manager.h
@@ -84,6 +84,11 @@ // be sent immediately. void WriteOrBufferHandshakeDone(); + // Tries to send an AckFrequencyFrame. The frame is buffered if it cannot be + // sent immediately. + void WriteOrBufferAckFrequency(uint64_t packet_tolerance, + QuicTime::Delta max_ack_delay); + // Sends a PING_FRAME. Do not send PING if there is buffered frames. void WritePing();
diff --git a/quic/core/quic_control_frame_manager_test.cc b/quic/core/quic_control_frame_manager_test.cc index 6219038..6817699 100644 --- a/quic/core/quic_control_frame_manager_test.cc +++ b/quic/core/quic_control_frame_manager_test.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" @@ -231,6 +232,29 @@ EXPECT_FALSE(manager_->WillingToWrite()); } +TEST_F(QuicControlFrameManagerTest, SendAndAckAckFrequencyFrame) { + Initialize(); + InSequence s; + // Send Non-AckFrequency frame 1-5. + EXPECT_CALL(*connection_, SendControlFrame(_)) + .Times(5) + .WillRepeatedly(Invoke(&ClearControlFrame)); + EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false)); + manager_->OnCanWrite(); + + // Send AckFrequencyFrame as frame 6. + QuicAckFrequencyFrame ack_frequency = {6, 6, 10, + QuicTime::Delta::FromMilliseconds(24)}; + manager_->WriteOrBufferAckFrequency(10, + QuicTime::Delta::FromMilliseconds(24)); + EXPECT_CALL(*connection_, SendControlFrame(_)) + .WillOnce(Invoke(&ClearControlFrame)); + manager_->OnCanWrite(); + + // Ack AckFrequencyFrame. + EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(&ack_frequency))); +} + TEST_F(QuicControlFrameManagerTest, DonotRetransmitOldWindowUpdates) { Initialize(); // Send two more window updates of the same stream.
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc index 939d78d..a3e2bf9 100644 --- a/quic/core/quic_packet_creator.cc +++ b/quic/core/quic_packet_creator.cc
@@ -503,6 +503,7 @@ packet_.transmission_type = NOT_RETRANSMISSION; packet_.encrypted_buffer = nullptr; packet_.encrypted_length = 0; + packet_.has_ack_frequency = false; packet_.fate = SEND_TO_WRITER; QUIC_BUG_IF(packet_.release_encrypted_buffer != nullptr) << "packet_.release_encrypted_buffer should be empty"; @@ -1686,9 +1687,10 @@ if (frame.type == ACK_FRAME) { packet_.has_ack = true; packet_.largest_acked = LargestAcked(*frame.ack_frame); - } - if (frame.type == STOP_WAITING_FRAME) { + } else if (frame.type == STOP_WAITING_FRAME) { packet_.has_stop_waiting = true; + } else if (frame.type == ACK_FREQUENCY_FRAME) { + packet_.has_ack_frequency = true; } if (debug_delegate_ != nullptr) { debug_delegate_->OnFrameAddedToPacket(frame);
diff --git a/quic/core/quic_packets.cc b/quic/core/quic_packets.cc index 30bf334..c975fe7 100644 --- a/quic/core/quic_packets.cc +++ b/quic/core/quic_packets.cc
@@ -463,6 +463,7 @@ has_stop_waiting(has_stop_waiting), transmission_type(NOT_RETRANSMISSION), has_ack_frame_copy(false), + has_ack_frequency(false), fate(SEND_TO_WRITER) {} SerializedPacket::SerializedPacket(SerializedPacket&& other) @@ -475,6 +476,7 @@ transmission_type(other.transmission_type), largest_acked(other.largest_acked), has_ack_frame_copy(other.has_ack_frame_copy), + has_ack_frequency(other.has_ack_frequency), fate(other.fate), peer_address(other.peer_address) { if (this != &other) { @@ -519,6 +521,7 @@ copy->encryption_level = serialized.encryption_level; copy->transmission_type = serialized.transmission_type; copy->largest_acked = serialized.largest_acked; + copy->has_ack_frequency = serialized.has_ack_frequency; copy->fate = serialized.fate; copy->peer_address = serialized.peer_address;
diff --git a/quic/core/quic_packets.h b/quic/core/quic_packets.h index e00bcda..5941c39 100644 --- a/quic/core/quic_packets.h +++ b/quic/core/quic_packets.h
@@ -403,6 +403,7 @@ // Indicates whether this packet has a copy of ack frame in // nonretransmittable_frames. bool has_ack_frame_copy; + bool has_ack_frequency; SerializedPacketFate fate; QuicSocketAddress peer_address; };
diff --git a/quic/core/quic_sent_packet_manager.cc b/quic/core/quic_sent_packet_manager.cc index c73fb9a..1a730e6 100644 --- a/quic/core/quic_sent_packet_manager.cc +++ b/quic/core/quic_sent_packet_manager.cc
@@ -645,6 +645,13 @@ QuicTime ack_receive_time, QuicTime::Delta ack_delay_time, QuicTime receive_timestamp) { + if (info->has_ack_frequency) { + for (const auto& frame : info->retransmittable_frames) { + if (frame.type == ACK_FREQUENCY_FRAME) { + OnAckFrequencyFrameAcked(*frame.ack_frequency_frame); + } + } + } // Try to aggregate acked stream frames if acked packet is not a // retransmission. if (info->transmission_type == NOT_RETRANSMISSION) { @@ -722,6 +729,13 @@ one_rtt_packet_sent_ = true; } + if (packet.has_ack_frequency) { + for (const auto& frame : packet.retransmittable_frames) { + if (frame.type == ACK_FREQUENCY_FRAME) { + OnAckFrequencyFrameSent(*frame.ack_frequency_frame); + } + } + } unacked_packets_.AddSentPacket(mutable_packet, transmission_type, sent_time, in_flight, measure_rtt); // Reset the retransmission timer anytime a pending packet is sent. @@ -1603,5 +1617,37 @@ : GetRetransmissionDelay(); } +void QuicSentPacketManager::OnAckFrequencyFrameSent( + const QuicAckFrequencyFrame& ack_frequency_frame) { + in_use_sent_ack_delays_.emplace_back(ack_frequency_frame.max_ack_delay, + ack_frequency_frame.sequence_number); + if (ack_frequency_frame.max_ack_delay > peer_max_ack_delay_) { + peer_max_ack_delay_ = ack_frequency_frame.max_ack_delay; + } +} + +void QuicSentPacketManager::OnAckFrequencyFrameAcked( + const QuicAckFrequencyFrame& ack_frequency_frame) { + int stale_entry_count = 0; + for (auto it = in_use_sent_ack_delays_.cbegin(); + it != in_use_sent_ack_delays_.cend(); ++it) { + if (it->second < ack_frequency_frame.sequence_number) { + ++stale_entry_count; + } else { + break; + } + } + if (stale_entry_count > 0) { + in_use_sent_ack_delays_.pop_front_n(stale_entry_count); + } + if (in_use_sent_ack_delays_.empty()) { + QUIC_BUG << "in_use_sent_ack_delays_ is empty."; + return; + } + peer_max_ack_delay_ = std::max_element(in_use_sent_ack_delays_.cbegin(), + in_use_sent_ack_delays_.cend()) + ->first; +} + #undef ENDPOINT // undef for jumbo builds } // namespace quic
diff --git a/quic/core/quic_sent_packet_manager.h b/quic/core/quic_sent_packet_manager.h index 6719a94..3420140 100644 --- a/quic/core/quic_sent_packet_manager.h +++ b/quic/core/quic_sent_packet_manager.h
@@ -6,6 +6,7 @@ #define QUICHE_QUIC_CORE_QUIC_SENT_PACKET_MANAGER_H_ #include <cstddef> +#include <cstdint> #include <map> #include <memory> #include <set> @@ -18,6 +19,7 @@ #include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h" #include "net/third_party/quiche/src/quic/core/congestion_control/uber_loss_algorithm.h" #include "net/third_party/quiche/src/quic/core/proto/cached_network_parameters_proto.h" +#include "net/third_party/quiche/src/quic/core/quic_circular_deque.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_sustained_bandwidth_recorder.h" #include "net/third_party/quiche/src/quic/core/quic_transmission_info.h" @@ -554,6 +556,14 @@ // retransmission timer is not armed if there is no packets in flight. bool PeerCompletedAddressValidation() const; + // Called when an AckFrequencyFrame is sent. + void OnAckFrequencyFrameSent( + const QuicAckFrequencyFrame& ack_frequency_frame); + + // Called when an AckFrequencyFrame is acked. + void OnAckFrequencyFrameAcked( + const QuicAckFrequencyFrame& ack_frequency_frame); + // Newly serialized retransmittable packets are added to this map, which // contains owning pointers to any contained frames. If a packet is // retransmitted, this map will contain entries for both the old and the new @@ -633,11 +643,17 @@ QuicPacketNumber largest_packets_peer_knows_is_acked_[NUM_PACKET_NUMBER_SPACES]; - // The maximum ACK delay time that the peer uses. Initialized to be the + // The maximum ACK delay time that the peer might uses. Initialized to be the // same as local_max_ack_delay_, may be changed via transport parameter - // negotiation. + // negotiation or subsequently by AckFrequencyFrame. QuicTime::Delta peer_max_ack_delay_; + // The history of outstanding max_ack_delays sent to peer. Outstanding means + // a max_ack_delay is sent as part of the last acked AckFrequencyFrame or + // an unacked AckFrequencyFrame after that. + QuicCircularDeque<std::pair<QuicTime::Delta, /*sequence_number=*/uint64_t>> + in_use_sent_ack_delays_; + // Latest received ack frame. QuicAckFrame last_ack_frame_;
diff --git a/quic/core/quic_sent_packet_manager_test.cc b/quic/core/quic_sent_packet_manager_test.cc index c5fb920..05da9df 100644 --- a/quic/core/quic_sent_packet_manager_test.cc +++ b/quic/core/quic_sent_packet_manager_test.cc
@@ -7,6 +7,8 @@ #include <memory> #include <utility> +#include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h" +#include "net/third_party/quiche/src/quic/core/quic_time.h" #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" @@ -4230,6 +4232,184 @@ ENCRYPTION_FORWARD_SECURE)); } +SerializedPacket MakePacketWithAckFrequencyFrame( + int packet_number, + int ack_frequency_sequence_number, + QuicTime::Delta max_ack_delay) { + auto* ack_frequency_frame = new QuicAckFrequencyFrame(); + ack_frequency_frame->max_ack_delay = max_ack_delay; + ack_frequency_frame->sequence_number = ack_frequency_sequence_number; + SerializedPacket packet(QuicPacketNumber(packet_number), + PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength, + /*has_ack=*/false, + /*has_stop_waiting=*/false); + packet.retransmittable_frames.push_back(QuicFrame(ack_frequency_frame)); + packet.has_ack_frequency = true; + packet.encryption_level = ENCRYPTION_FORWARD_SECURE; + return packet; +} + +TEST_F(QuicSentPacketManagerTest, + PeerMaxAckDelayUpdatedFromAckFrequencyFrameOneAtATime) { + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber()); + EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)) + .Times(AnyNumber()); + EXPECT_CALL(*network_change_visitor_, OnCongestionChange()) + .Times(AnyNumber()); + + auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay(); + auto one_ms = QuicTime::Delta::FromMilliseconds(1); + auto plus_1_ms_delay = initial_peer_max_ack_delay + one_ms; + auto minus_1_ms_delay = initial_peer_max_ack_delay - one_ms; + + // Send and Ack frame1. + SerializedPacket packet1 = MakePacketWithAckFrequencyFrame( + /*packet_number=*/1, /*ack_frequency_sequence_number=*/1, + plus_1_ms_delay); + // Higher on the fly max_ack_delay changes peer_max_ack_delay. + manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION, + HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true); + EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay); + manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2)); + manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1), + ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay); + + // Send and Ack frame2. + SerializedPacket packet2 = MakePacketWithAckFrequencyFrame( + /*packet_number=*/2, /*ack_frequency_sequence_number=*/2, + minus_1_ms_delay); + // Lower on the fly max_ack_delay does not change peer_max_ack_delay. + manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION, + HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true); + EXPECT_EQ(manager_.peer_max_ack_delay(), plus_1_ms_delay); + manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3)); + manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(2), + ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ(manager_.peer_max_ack_delay(), minus_1_ms_delay); +} + +TEST_F(QuicSentPacketManagerTest, + PeerMaxAckDelayUpdatedFromInOrderAckFrequencyFrames) { + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber()); + EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)) + .Times(AnyNumber()); + EXPECT_CALL(*network_change_visitor_, OnCongestionChange()) + .Times(AnyNumber()); + + auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay(); + auto one_ms = QuicTime::Delta::FromMilliseconds(1); + auto extra_1_ms = initial_peer_max_ack_delay + one_ms; + auto extra_2_ms = initial_peer_max_ack_delay + 2 * one_ms; + auto extra_3_ms = initial_peer_max_ack_delay + 3 * one_ms; + SerializedPacket packet1 = MakePacketWithAckFrequencyFrame( + /*packet_number=*/1, /*ack_frequency_sequence_number=*/1, extra_1_ms); + SerializedPacket packet2 = MakePacketWithAckFrequencyFrame( + /*packet_number=*/2, /*ack_frequency_sequence_number=*/2, extra_3_ms); + SerializedPacket packet3 = MakePacketWithAckFrequencyFrame( + /*packet_number=*/3, /*ack_frequency_sequence_number=*/3, extra_2_ms); + + // Send frame1, farme2, frame3. + manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION, + HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true); + EXPECT_EQ(manager_.peer_max_ack_delay(), extra_1_ms); + manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION, + HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true); + EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms); + manager_.OnPacketSent(&packet3, clock_.Now(), NOT_RETRANSMISSION, + HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true); + EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms); + + // Ack frame1, farme2, frame3. + manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2)); + manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1), + ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms); + manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3)); + manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1), + ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ(manager_.peer_max_ack_delay(), extra_3_ms); + manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4)); + manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1), + ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms); +} + +TEST_F(QuicSentPacketManagerTest, + PeerMaxAckDelayUpdatedFromOutOfOrderAckedAckFrequencyFrames) { + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber()); + EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)) + .Times(AnyNumber()); + EXPECT_CALL(*network_change_visitor_, OnCongestionChange()) + .Times(AnyNumber()); + + auto initial_peer_max_ack_delay = manager_.peer_max_ack_delay(); + auto one_ms = QuicTime::Delta::FromMilliseconds(1); + auto extra_1_ms = initial_peer_max_ack_delay + one_ms; + auto extra_2_ms = initial_peer_max_ack_delay + 2 * one_ms; + auto extra_3_ms = initial_peer_max_ack_delay + 3 * one_ms; + auto extra_4_ms = initial_peer_max_ack_delay + 4 * one_ms; + SerializedPacket packet1 = MakePacketWithAckFrequencyFrame( + /*packet_number=*/1, /*ack_frequency_sequence_number=*/1, extra_4_ms); + SerializedPacket packet2 = MakePacketWithAckFrequencyFrame( + /*packet_number=*/2, /*ack_frequency_sequence_number=*/2, extra_3_ms); + SerializedPacket packet3 = MakePacketWithAckFrequencyFrame( + /*packet_number=*/3, /*ack_frequency_sequence_number=*/3, extra_2_ms); + SerializedPacket packet4 = MakePacketWithAckFrequencyFrame( + /*packet_number=*/4, /*ack_frequency_sequence_number=*/4, extra_1_ms); + + // Send frame1, farme2, frame3, frame4. + manager_.OnPacketSent(&packet1, clock_.Now(), NOT_RETRANSMISSION, + HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true); + manager_.OnPacketSent(&packet2, clock_.Now(), NOT_RETRANSMISSION, + HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true); + manager_.OnPacketSent(&packet3, clock_.Now(), NOT_RETRANSMISSION, + HAS_RETRANSMITTABLE_DATA, /*measure_rtt=*/true); + manager_.OnPacketSent(&packet4, clock_.Now(), NOT_RETRANSMISSION, + NO_RETRANSMITTABLE_DATA, /*measure_rtt=*/true); + EXPECT_EQ(manager_.peer_max_ack_delay(), extra_4_ms); + + // Ack frame3. + manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4)); + manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1), + ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms); + // Acking frame1 do not affect peer_max_ack_delay after frame3 is acked. + manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4)); + manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2)); + manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1), + ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms); + // Acking frame2 do not affect peer_max_ack_delay after frame3 is acked. + manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4)); + manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1), + ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ(manager_.peer_max_ack_delay(), extra_2_ms); + // Acking frame4 updates peer_max_ack_delay. + manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(), + clock_.Now()); + manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(5)); + manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1), + ENCRYPTION_FORWARD_SECURE); + EXPECT_EQ(manager_.peer_max_ack_delay(), extra_1_ms); +} + } // namespace } // namespace test } // namespace quic
diff --git a/quic/core/quic_transmission_info.cc b/quic/core/quic_transmission_info.cc index a27b769..02b34b5 100644 --- a/quic/core/quic_transmission_info.cc +++ b/quic/core/quic_transmission_info.cc
@@ -13,20 +13,23 @@ transmission_type(NOT_RETRANSMISSION), in_flight(false), state(OUTSTANDING), - has_crypto_handshake(false) {} + has_crypto_handshake(false), + has_ack_frequency(false) {} QuicTransmissionInfo::QuicTransmissionInfo(EncryptionLevel level, TransmissionType transmission_type, QuicTime sent_time, QuicPacketLength bytes_sent, - bool has_crypto_handshake) + bool has_crypto_handshake, + bool has_ack_frequency) : encryption_level(level), bytes_sent(bytes_sent), sent_time(sent_time), transmission_type(transmission_type), in_flight(false), state(OUTSTANDING), - has_crypto_handshake(has_crypto_handshake) {} + has_crypto_handshake(has_crypto_handshake), + has_ack_frequency(has_ack_frequency) {} QuicTransmissionInfo::QuicTransmissionInfo(const QuicTransmissionInfo& other) = default;
diff --git a/quic/core/quic_transmission_info.h b/quic/core/quic_transmission_info.h index 6023665..acc5667 100644 --- a/quic/core/quic_transmission_info.h +++ b/quic/core/quic_transmission_info.h
@@ -25,7 +25,8 @@ TransmissionType transmission_type, QuicTime sent_time, QuicPacketLength bytes_sent, - bool has_crypto_handshake); + bool has_crypto_handshake, + bool has_ack_frequency); QuicTransmissionInfo(const QuicTransmissionInfo& other); @@ -43,6 +44,8 @@ SentPacketState state; // True if the packet contains stream data from the crypto stream. bool has_crypto_handshake; + // True if the packet contains ack frequency frame. + bool has_ack_frequency; // Records the first sent packet after this packet was detected lost. Zero if // this packet has not been detected lost. This is used to keep lost packet // for another RTT (for potential spurious loss detection)
diff --git a/quic/core/quic_unacked_packet_map.cc b/quic/core/quic_unacked_packet_map.cc index 3d5579d..3e377cf 100644 --- a/quic/core/quic_unacked_packet_map.cc +++ b/quic/core/quic_unacked_packet_map.cc
@@ -148,7 +148,8 @@ const bool has_crypto_handshake = packet.has_crypto_handshake == IS_HANDSHAKE; QuicTransmissionInfo info(packet.encryption_level, transmission_type, - sent_time, bytes_sent, has_crypto_handshake); + sent_time, bytes_sent, has_crypto_handshake, + packet.has_ack_frequency); info.largest_acked = packet.largest_acked; largest_sent_largest_acked_.UpdateMax(packet.largest_acked);