1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "quiche/quic/core/congestion_control/general_loss_algorithm.h"
6
7 #include <algorithm>
8 #include <cstdint>
9
10 #include "quiche/quic/core/congestion_control/rtt_stats.h"
11 #include "quiche/quic/core/quic_unacked_packet_map.h"
12 #include "quiche/quic/core/quic_utils.h"
13 #include "quiche/quic/platform/api/quic_flags.h"
14 #include "quiche/quic/platform/api/quic_test.h"
15 #include "quiche/quic/test_tools/mock_clock.h"
16
17 namespace quic {
18 namespace test {
19 namespace {
20
21 // Default packet length.
22 const uint32_t kDefaultLength = 1000;
23
24 class GeneralLossAlgorithmTest : public QuicTest {
25 protected:
GeneralLossAlgorithmTest()26 GeneralLossAlgorithmTest() : unacked_packets_(Perspective::IS_CLIENT) {
27 rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
28 QuicTime::Delta::Zero(), clock_.Now());
29 EXPECT_LT(0, rtt_stats_.smoothed_rtt().ToMicroseconds());
30 loss_algorithm_.Initialize(HANDSHAKE_DATA, nullptr);
31 }
32
~GeneralLossAlgorithmTest()33 ~GeneralLossAlgorithmTest() override {}
34
SendDataPacket(uint64_t packet_number,QuicPacketLength encrypted_length)35 void SendDataPacket(uint64_t packet_number,
36 QuicPacketLength encrypted_length) {
37 QuicStreamFrame frame;
38 frame.stream_id = QuicUtils::GetFirstBidirectionalStreamId(
39 CurrentSupportedVersions()[0].transport_version,
40 Perspective::IS_CLIENT);
41 SerializedPacket packet(QuicPacketNumber(packet_number),
42 PACKET_1BYTE_PACKET_NUMBER, nullptr,
43 encrypted_length, false, false);
44 packet.retransmittable_frames.push_back(QuicFrame(frame));
45 unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
46 true, true, ECN_NOT_ECT);
47 }
48
SendDataPacket(uint64_t packet_number)49 void SendDataPacket(uint64_t packet_number) {
50 SendDataPacket(packet_number, kDefaultLength);
51 }
52
SendAckPacket(uint64_t packet_number)53 void SendAckPacket(uint64_t packet_number) {
54 SerializedPacket packet(QuicPacketNumber(packet_number),
55 PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
56 true, false);
57 unacked_packets_.AddSentPacket(&packet, NOT_RETRANSMISSION, clock_.Now(),
58 false, true, ECN_NOT_ECT);
59 }
60
VerifyLosses(uint64_t largest_newly_acked,const AckedPacketVector & packets_acked,const std::vector<uint64_t> & losses_expected)61 void VerifyLosses(uint64_t largest_newly_acked,
62 const AckedPacketVector& packets_acked,
63 const std::vector<uint64_t>& losses_expected) {
64 return VerifyLosses(largest_newly_acked, packets_acked, losses_expected,
65 std::nullopt, std::nullopt);
66 }
67
VerifyLosses(uint64_t largest_newly_acked,const AckedPacketVector & packets_acked,const std::vector<uint64_t> & losses_expected,std::optional<QuicPacketCount> max_sequence_reordering_expected,std::optional<QuicPacketCount> num_borderline_time_reorderings_expected)68 void VerifyLosses(
69 uint64_t largest_newly_acked, const AckedPacketVector& packets_acked,
70 const std::vector<uint64_t>& losses_expected,
71 std::optional<QuicPacketCount> max_sequence_reordering_expected,
72 std::optional<QuicPacketCount> num_borderline_time_reorderings_expected) {
73 unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
74 APPLICATION_DATA, QuicPacketNumber(largest_newly_acked));
75 LostPacketVector lost_packets;
76 LossDetectionInterface::DetectionStats stats = loss_algorithm_.DetectLosses(
77 unacked_packets_, clock_.Now(), rtt_stats_,
78 QuicPacketNumber(largest_newly_acked), packets_acked, &lost_packets);
79 if (max_sequence_reordering_expected.has_value()) {
80 EXPECT_EQ(stats.sent_packets_max_sequence_reordering,
81 max_sequence_reordering_expected.value());
82 }
83 if (num_borderline_time_reorderings_expected.has_value()) {
84 EXPECT_EQ(stats.sent_packets_num_borderline_time_reorderings,
85 num_borderline_time_reorderings_expected.value());
86 }
87 ASSERT_EQ(losses_expected.size(), lost_packets.size());
88 for (size_t i = 0; i < losses_expected.size(); ++i) {
89 EXPECT_EQ(lost_packets[i].packet_number,
90 QuicPacketNumber(losses_expected[i]));
91 }
92 }
93
94 QuicUnackedPacketMap unacked_packets_;
95 GeneralLossAlgorithm loss_algorithm_;
96 RttStats rtt_stats_;
97 MockClock clock_;
98 };
99
TEST_F(GeneralLossAlgorithmTest,NackRetransmit1Packet)100 TEST_F(GeneralLossAlgorithmTest, NackRetransmit1Packet) {
101 const size_t kNumSentPackets = 5;
102 // Transmit 5 packets.
103 for (size_t i = 1; i <= kNumSentPackets; ++i) {
104 SendDataPacket(i);
105 }
106 AckedPacketVector packets_acked;
107 // No loss on one ack.
108 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
109 packets_acked.push_back(AckedPacket(
110 QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
111 VerifyLosses(2, packets_acked, std::vector<uint64_t>{}, 1, 0);
112 packets_acked.clear();
113 // No loss on two acks.
114 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
115 packets_acked.push_back(AckedPacket(
116 QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
117 VerifyLosses(3, packets_acked, std::vector<uint64_t>{}, 2, 0);
118 packets_acked.clear();
119 // Loss on three acks.
120 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
121 packets_acked.push_back(AckedPacket(
122 QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
123 VerifyLosses(4, packets_acked, {1}, 3, 0);
124 EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
125 }
126
127 // A stretch ack is an ack that covers more than 1 packet of previously
128 // unacknowledged data.
TEST_F(GeneralLossAlgorithmTest,NackRetransmit1PacketWith1StretchAck)129 TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketWith1StretchAck) {
130 const size_t kNumSentPackets = 10;
131 // Transmit 10 packets.
132 for (size_t i = 1; i <= kNumSentPackets; ++i) {
133 SendDataPacket(i);
134 }
135 AckedPacketVector packets_acked;
136 // Nack the first packet 3 times in a single StretchAck.
137 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
138 packets_acked.push_back(AckedPacket(
139 QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
140 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
141 packets_acked.push_back(AckedPacket(
142 QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
143 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
144 packets_acked.push_back(AckedPacket(
145 QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
146 VerifyLosses(4, packets_acked, {1});
147 EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
148 }
149
150 // Ack a packet 3 packets ahead, causing a retransmit.
TEST_F(GeneralLossAlgorithmTest,NackRetransmit1PacketSingleAck)151 TEST_F(GeneralLossAlgorithmTest, NackRetransmit1PacketSingleAck) {
152 const size_t kNumSentPackets = 10;
153 // Transmit 10 packets.
154 for (size_t i = 1; i <= kNumSentPackets; ++i) {
155 SendDataPacket(i);
156 }
157 AckedPacketVector packets_acked;
158 // Nack the first packet 3 times in an AckFrame with three missing packets.
159 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
160 packets_acked.push_back(AckedPacket(
161 QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
162 VerifyLosses(4, packets_acked, {1});
163 EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
164 loss_algorithm_.GetLossTimeout());
165 }
166
TEST_F(GeneralLossAlgorithmTest,EarlyRetransmit1Packet)167 TEST_F(GeneralLossAlgorithmTest, EarlyRetransmit1Packet) {
168 const size_t kNumSentPackets = 2;
169 // Transmit 2 packets.
170 for (size_t i = 1; i <= kNumSentPackets; ++i) {
171 SendDataPacket(i);
172 }
173 AckedPacketVector packets_acked;
174 // Early retransmit when the final packet gets acked and the first is nacked.
175 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
176 packets_acked.push_back(AckedPacket(
177 QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
178 VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
179 packets_acked.clear();
180 EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
181 loss_algorithm_.GetLossTimeout());
182
183 clock_.AdvanceTime(1.13 * rtt_stats_.latest_rtt());
184 // If reordering_shift increases by one we should have detected a loss.
185 VerifyLosses(2, packets_acked, {}, /*max_sequence_reordering_expected=*/1,
186 /*num_borderline_time_reorderings_expected=*/1);
187
188 clock_.AdvanceTime(0.13 * rtt_stats_.latest_rtt());
189 VerifyLosses(2, packets_acked, {1});
190 EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
191 }
192
TEST_F(GeneralLossAlgorithmTest,EarlyRetransmitAllPackets)193 TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitAllPackets) {
194 const size_t kNumSentPackets = 5;
195 for (size_t i = 1; i <= kNumSentPackets; ++i) {
196 SendDataPacket(i);
197 // Advance the time 1/4 RTT between 3 and 4.
198 if (i == 3) {
199 clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
200 }
201 }
202 AckedPacketVector packets_acked;
203 // Early retransmit when the final packet gets acked and 1.25 RTTs have
204 // elapsed since the packets were sent.
205 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(kNumSentPackets));
206 packets_acked.push_back(AckedPacket(QuicPacketNumber(kNumSentPackets),
207 kMaxOutgoingPacketSize,
208 QuicTime::Zero()));
209 // This simulates a single ack following multiple missing packets with FACK.
210 VerifyLosses(kNumSentPackets, packets_acked, {1, 2});
211 packets_acked.clear();
212 // The time has already advanced 1/4 an RTT, so ensure the timeout is set
213 // 1.25 RTTs after the earliest pending packet(3), not the last(4).
214 EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt(),
215 loss_algorithm_.GetLossTimeout());
216
217 clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
218 VerifyLosses(kNumSentPackets, packets_acked, {3});
219 EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
220 loss_algorithm_.GetLossTimeout());
221 clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
222 VerifyLosses(kNumSentPackets, packets_acked, {4});
223 EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
224 }
225
TEST_F(GeneralLossAlgorithmTest,DontEarlyRetransmitNeuteredPacket)226 TEST_F(GeneralLossAlgorithmTest, DontEarlyRetransmitNeuteredPacket) {
227 const size_t kNumSentPackets = 2;
228 // Transmit 2 packets.
229 for (size_t i = 1; i <= kNumSentPackets; ++i) {
230 SendDataPacket(i);
231 }
232 AckedPacketVector packets_acked;
233 // Neuter packet 1.
234 unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
235 clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
236
237 // Early retransmit when the final packet gets acked and the first is nacked.
238 unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
239 APPLICATION_DATA, QuicPacketNumber(2));
240 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
241 packets_acked.push_back(AckedPacket(
242 QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
243 VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
244 EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
245 loss_algorithm_.GetLossTimeout());
246 }
247
TEST_F(GeneralLossAlgorithmTest,EarlyRetransmitWithLargerUnackablePackets)248 TEST_F(GeneralLossAlgorithmTest, EarlyRetransmitWithLargerUnackablePackets) {
249 // Transmit 2 data packets and one ack.
250 SendDataPacket(1);
251 SendDataPacket(2);
252 SendAckPacket(3);
253 AckedPacketVector packets_acked;
254 clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
255
256 // Early retransmit when the final packet gets acked and the first is nacked.
257 unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
258 APPLICATION_DATA, QuicPacketNumber(2));
259 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
260 packets_acked.push_back(AckedPacket(
261 QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
262 VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
263 packets_acked.clear();
264 EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
265 loss_algorithm_.GetLossTimeout());
266
267 // The packet should be lost once the loss timeout is reached.
268 clock_.AdvanceTime(0.25 * rtt_stats_.latest_rtt());
269 VerifyLosses(2, packets_acked, {1});
270 EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
271 }
272
TEST_F(GeneralLossAlgorithmTest,AlwaysLosePacketSent1RTTEarlier)273 TEST_F(GeneralLossAlgorithmTest, AlwaysLosePacketSent1RTTEarlier) {
274 // Transmit 1 packet and then wait an rtt plus 1ms.
275 SendDataPacket(1);
276 clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
277 QuicTime::Delta::FromMilliseconds(1));
278
279 // Transmit 2 packets.
280 SendDataPacket(2);
281 SendDataPacket(3);
282 AckedPacketVector packets_acked;
283 // Wait another RTT and ack 2.
284 clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
285 unacked_packets_.MaybeUpdateLargestAckedOfPacketNumberSpace(
286 APPLICATION_DATA, QuicPacketNumber(2));
287 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
288 packets_acked.push_back(AckedPacket(
289 QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
290 VerifyLosses(2, packets_acked, {1});
291 }
292
TEST_F(GeneralLossAlgorithmTest,IncreaseTimeThresholdUponSpuriousLoss)293 TEST_F(GeneralLossAlgorithmTest, IncreaseTimeThresholdUponSpuriousLoss) {
294 loss_algorithm_.enable_adaptive_time_threshold();
295 loss_algorithm_.set_reordering_shift(kDefaultLossDelayShift);
296 EXPECT_EQ(kDefaultLossDelayShift, loss_algorithm_.reordering_shift());
297 EXPECT_TRUE(loss_algorithm_.use_adaptive_time_threshold());
298 const size_t kNumSentPackets = 10;
299 // Transmit 2 packets at 1/10th an RTT interval.
300 for (size_t i = 1; i <= kNumSentPackets; ++i) {
301 SendDataPacket(i);
302 clock_.AdvanceTime(0.1 * rtt_stats_.smoothed_rtt());
303 }
304 EXPECT_EQ(QuicTime::Zero() + rtt_stats_.smoothed_rtt(), clock_.Now());
305 AckedPacketVector packets_acked;
306 // Expect the timer to not be set.
307 EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
308 // Packet 1 should not be lost until 1/4 RTTs pass.
309 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
310 packets_acked.push_back(AckedPacket(
311 QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
312 VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
313 packets_acked.clear();
314 // Expect the timer to be set to 1/4 RTT's in the future.
315 EXPECT_EQ(rtt_stats_.smoothed_rtt() * (1.0f / 4),
316 loss_algorithm_.GetLossTimeout() - clock_.Now());
317 VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
318 clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4));
319 VerifyLosses(2, packets_acked, {1});
320 EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
321 // Retransmit packet 1 as 11 and 2 as 12.
322 SendDataPacket(11);
323 SendDataPacket(12);
324
325 // Advance the time 1/4 RTT and indicate the loss was spurious.
326 // The new threshold should be 1/2 RTT.
327 clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 4));
328 loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
329 clock_.Now(), QuicPacketNumber(1),
330 QuicPacketNumber(2));
331 EXPECT_EQ(1, loss_algorithm_.reordering_shift());
332 }
333
TEST_F(GeneralLossAlgorithmTest,IncreaseReorderingThresholdUponSpuriousLoss)334 TEST_F(GeneralLossAlgorithmTest, IncreaseReorderingThresholdUponSpuriousLoss) {
335 loss_algorithm_.set_use_adaptive_reordering_threshold(true);
336 for (size_t i = 1; i <= 4; ++i) {
337 SendDataPacket(i);
338 }
339 // Acking 4 causes 1 detected lost.
340 AckedPacketVector packets_acked;
341 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
342 packets_acked.push_back(AckedPacket(
343 QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
344 VerifyLosses(4, packets_acked, std::vector<uint64_t>{1});
345 packets_acked.clear();
346
347 // Retransmit 1 as 5.
348 SendDataPacket(5);
349
350 // Acking 1 such that it was detected lost spuriously.
351 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
352 packets_acked.push_back(AckedPacket(
353 QuicPacketNumber(1), kMaxOutgoingPacketSize, QuicTime::Zero()));
354 loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
355 clock_.Now(), QuicPacketNumber(1),
356 QuicPacketNumber(4));
357 VerifyLosses(4, packets_acked, std::vector<uint64_t>{});
358 packets_acked.clear();
359
360 // Verify acking 5 does not cause 2 detected lost.
361 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
362 packets_acked.push_back(AckedPacket(
363 QuicPacketNumber(5), kMaxOutgoingPacketSize, QuicTime::Zero()));
364 VerifyLosses(5, packets_acked, std::vector<uint64_t>{});
365 packets_acked.clear();
366
367 SendDataPacket(6);
368
369 // Acking 6 will causes 2 detected lost.
370 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
371 packets_acked.push_back(AckedPacket(
372 QuicPacketNumber(6), kMaxOutgoingPacketSize, QuicTime::Zero()));
373 VerifyLosses(6, packets_acked, std::vector<uint64_t>{2});
374 packets_acked.clear();
375
376 // Retransmit 2 as 7.
377 SendDataPacket(7);
378
379 // Acking 2 such that it was detected lost spuriously.
380 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
381 packets_acked.push_back(AckedPacket(
382 QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
383 loss_algorithm_.SpuriousLossDetected(unacked_packets_, rtt_stats_,
384 clock_.Now(), QuicPacketNumber(2),
385 QuicPacketNumber(6));
386 VerifyLosses(6, packets_acked, std::vector<uint64_t>{});
387 packets_acked.clear();
388
389 // Acking 7 will not cause 3 as detected lost.
390 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(7));
391 packets_acked.push_back(AckedPacket(
392 QuicPacketNumber(7), kMaxOutgoingPacketSize, QuicTime::Zero()));
393 VerifyLosses(7, packets_acked, std::vector<uint64_t>{});
394 packets_acked.clear();
395 }
396
TEST_F(GeneralLossAlgorithmTest,DefaultIetfLossDetection)397 TEST_F(GeneralLossAlgorithmTest, DefaultIetfLossDetection) {
398 loss_algorithm_.set_reordering_shift(kDefaultIetfLossDelayShift);
399 for (size_t i = 1; i <= 6; ++i) {
400 SendDataPacket(i);
401 }
402 // Packet threshold loss detection.
403 AckedPacketVector packets_acked;
404 // No loss on one ack.
405 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
406 packets_acked.push_back(AckedPacket(
407 QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
408 VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
409 packets_acked.clear();
410 // No loss on two acks.
411 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
412 packets_acked.push_back(AckedPacket(
413 QuicPacketNumber(3), kMaxOutgoingPacketSize, QuicTime::Zero()));
414 VerifyLosses(3, packets_acked, std::vector<uint64_t>{});
415 packets_acked.clear();
416 // Loss on three acks.
417 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
418 packets_acked.push_back(AckedPacket(
419 QuicPacketNumber(4), kMaxOutgoingPacketSize, QuicTime::Zero()));
420 VerifyLosses(4, packets_acked, {1});
421 EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
422 packets_acked.clear();
423
424 SendDataPacket(7);
425
426 // Time threshold loss detection.
427 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
428 packets_acked.push_back(AckedPacket(
429 QuicPacketNumber(6), kMaxOutgoingPacketSize, QuicTime::Zero()));
430 VerifyLosses(6, packets_acked, std::vector<uint64_t>{});
431 packets_acked.clear();
432 EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
433 (rtt_stats_.smoothed_rtt() >> 3),
434 loss_algorithm_.GetLossTimeout());
435 clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
436 (rtt_stats_.smoothed_rtt() >> 3));
437 VerifyLosses(6, packets_acked, {5});
438 EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
439 }
440
TEST_F(GeneralLossAlgorithmTest,IetfLossDetectionWithOneFourthRttDelay)441 TEST_F(GeneralLossAlgorithmTest, IetfLossDetectionWithOneFourthRttDelay) {
442 loss_algorithm_.set_reordering_shift(2);
443 SendDataPacket(1);
444 SendDataPacket(2);
445
446 AckedPacketVector packets_acked;
447 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
448 packets_acked.push_back(AckedPacket(
449 QuicPacketNumber(2), kMaxOutgoingPacketSize, QuicTime::Zero()));
450 VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
451 packets_acked.clear();
452 EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
453 (rtt_stats_.smoothed_rtt() >> 2),
454 loss_algorithm_.GetLossTimeout());
455 clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
456 (rtt_stats_.smoothed_rtt() >> 2));
457 VerifyLosses(2, packets_acked, {1});
458 EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
459 }
460
TEST_F(GeneralLossAlgorithmTest,NoPacketThresholdForRuntPackets)461 TEST_F(GeneralLossAlgorithmTest, NoPacketThresholdForRuntPackets) {
462 loss_algorithm_.disable_packet_threshold_for_runt_packets();
463 for (size_t i = 1; i <= 6; ++i) {
464 SendDataPacket(i);
465 }
466 // Send a small packet.
467 SendDataPacket(7, /*encrypted_length=*/kDefaultLength / 2);
468 // No packet threshold for runt packet.
469 AckedPacketVector packets_acked;
470 unacked_packets_.RemoveFromInFlight(QuicPacketNumber(7));
471 packets_acked.push_back(AckedPacket(
472 QuicPacketNumber(7), kMaxOutgoingPacketSize, QuicTime::Zero()));
473 // Verify no packet is detected lost because packet 7 is a runt.
474 VerifyLosses(7, packets_acked, std::vector<uint64_t>{});
475 EXPECT_EQ(clock_.Now() + rtt_stats_.smoothed_rtt() +
476 (rtt_stats_.smoothed_rtt() >> 2),
477 loss_algorithm_.GetLossTimeout());
478 clock_.AdvanceTime(rtt_stats_.smoothed_rtt() +
479 (rtt_stats_.smoothed_rtt() >> 2));
480 // Verify packets are declared lost because time threshold has passed.
481 VerifyLosses(7, packets_acked, {1, 2, 3, 4, 5, 6});
482 EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
483 }
484
485 } // namespace
486 } // namespace test
487 } // namespace quic
488