OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/congestion_control/general_loss_algorithm.h" | 5 #include "net/quic/congestion_control/general_loss_algorithm.h" |
6 | 6 |
7 #include "net/quic/congestion_control/rtt_stats.h" | 7 #include "net/quic/congestion_control/rtt_stats.h" |
8 #include "net/quic/quic_bug_tracker.h" | 8 #include "net/quic/quic_bug_tracker.h" |
| 9 #include "net/quic/quic_flags.h" |
9 #include "net/quic/quic_protocol.h" | 10 #include "net/quic/quic_protocol.h" |
10 | 11 |
11 namespace net { | 12 namespace net { |
12 | 13 |
13 namespace { | 14 namespace { |
14 | 15 |
15 // The minimum delay before a packet will be considered lost, | 16 // The minimum delay before a packet will be considered lost, |
16 // regardless of SRTT. Half of the minimum TLP, since the loss algorithm only | 17 // regardless of SRTT. Half of the minimum TLP, since the loss algorithm only |
17 // triggers when a nack has been receieved for the packet. | 18 // triggers when a nack has been receieved for the packet. |
18 static const size_t kMinLossDelayMs = 5; | 19 static const size_t kMinLossDelayMs = 5; |
(...skipping 28 matching lines...) Expand all Loading... |
47 .Multiply(kLossDelayMultiplier)); | 48 .Multiply(kLossDelayMultiplier)); |
48 | 49 |
49 QuicPacketNumber packet_number = unacked_packets.GetLeastUnacked(); | 50 QuicPacketNumber packet_number = unacked_packets.GetLeastUnacked(); |
50 for (QuicUnackedPacketMap::const_iterator it = unacked_packets.begin(); | 51 for (QuicUnackedPacketMap::const_iterator it = unacked_packets.begin(); |
51 it != unacked_packets.end() && packet_number <= largest_observed; | 52 it != unacked_packets.end() && packet_number <= largest_observed; |
52 ++it, ++packet_number) { | 53 ++it, ++packet_number) { |
53 if (!it->in_flight) { | 54 if (!it->in_flight) { |
54 continue; | 55 continue; |
55 } | 56 } |
56 | 57 |
57 // TODO(ianswett): Combine this and the time based detection for FACK. | 58 if (FLAGS_quic_simplify_loss_detection && loss_type_ == kNack) { |
58 if (loss_type_ == kTime) { | 59 // FACK based loss detection. |
| 60 // TODO(ianswett): Pass in largest_newly_acked for FACK. |
| 61 if (largest_observed - packet_number >= |
| 62 kNumberOfNacksBeforeRetransmission) { |
| 63 packets_lost->push_back(std::make_pair(packet_number, it->bytes_sent)); |
| 64 continue; |
| 65 } |
| 66 } |
| 67 |
| 68 // Only early retransmit(RFC5827) when the last packet gets acked and |
| 69 // there are retransmittable packets in flight. |
| 70 // This also implements a timer-protected variant of FACK. |
| 71 if ((FLAGS_quic_simplify_loss_detection && |
| 72 !it->retransmittable_frames.empty() && |
| 73 unacked_packets.largest_sent_packet() == largest_observed) || |
| 74 loss_type_ == kTime) { |
59 QuicTime when_lost = it->sent_time.Add(loss_delay); | 75 QuicTime when_lost = it->sent_time.Add(loss_delay); |
60 if (time < when_lost) { | 76 if (time < when_lost) { |
61 loss_detection_timeout_ = when_lost; | 77 loss_detection_timeout_ = when_lost; |
62 break; | 78 break; |
63 } | 79 } |
64 packets_lost->push_back(std::make_pair(packet_number, it->bytes_sent)); | 80 packets_lost->push_back(std::make_pair(packet_number, it->bytes_sent)); |
65 continue; | 81 continue; |
66 } | 82 } |
67 | 83 if (!FLAGS_quic_simplify_loss_detection) { |
68 // FACK based loss detection. | 84 // FACK based loss detection. |
69 QUIC_BUG_IF(it->nack_count == 0 && it->sent_time.IsInitialized()) | 85 QUIC_BUG_IF(it->nack_count == 0 && it->sent_time.IsInitialized()) |
70 << "All packets less than largest observed should have been nacked." | 86 << "All packets less than largest observed should have been nacked." |
71 << " packet_number:" << packet_number | 87 << " packet_number:" << packet_number |
72 << " largest_observed:" << largest_observed; | 88 << " largest_observed:" << largest_observed; |
73 if (it->nack_count >= kNumberOfNacksBeforeRetransmission) { | 89 if (it->nack_count >= kNumberOfNacksBeforeRetransmission) { |
74 packets_lost->push_back(std::make_pair(packet_number, it->bytes_sent)); | 90 packets_lost->push_back(std::make_pair(packet_number, it->bytes_sent)); |
75 continue; | 91 continue; |
| 92 } |
76 } | 93 } |
77 | 94 |
78 // NACK-based loss detection allows for a max reordering window of 1 RTT. | 95 // NACK-based loss detection allows for a max reordering window of 1 RTT. |
79 if (it->sent_time.Add(rtt_stats.smoothed_rtt()) < | 96 if (it->sent_time.Add(rtt_stats.smoothed_rtt()) < |
80 unacked_packets.GetTransmissionInfo(largest_observed).sent_time) { | 97 unacked_packets.GetTransmissionInfo(largest_observed).sent_time) { |
81 packets_lost->push_back(std::make_pair(packet_number, it->bytes_sent)); | 98 packets_lost->push_back(std::make_pair(packet_number, it->bytes_sent)); |
82 continue; | 99 continue; |
83 } | 100 } |
84 | 101 |
85 // Only early retransmit(RFC5827) when the last packet gets acked and | 102 if (!FLAGS_quic_simplify_loss_detection && |
86 // there are retransmittable packets in flight. | 103 !it->retransmittable_frames.empty() && |
87 // This also implements a timer-protected variant of FACK. | |
88 if (!it->retransmittable_frames.empty() && | |
89 unacked_packets.largest_sent_packet() == largest_observed) { | 104 unacked_packets.largest_sent_packet() == largest_observed) { |
90 // Early retransmit marks the packet as lost once 1.25RTTs have passed | 105 // Early retransmit marks the packet as lost once 1.25RTTs have passed |
91 // since the packet was sent and otherwise sets an alarm. | 106 // since the packet was sent and otherwise sets an alarm. |
92 if (time >= it->sent_time.Add(loss_delay)) { | 107 if (time >= it->sent_time.Add(loss_delay)) { |
93 packets_lost->push_back(std::make_pair(packet_number, it->bytes_sent)); | 108 packets_lost->push_back(std::make_pair(packet_number, it->bytes_sent)); |
94 } else { | 109 } else { |
95 // Set the timeout for the earliest retransmittable packet where early | 110 // Set the timeout for the earliest retransmittable packet where early |
96 // retransmit applies. | 111 // retransmit applies. |
97 loss_detection_timeout_ = it->sent_time.Add(loss_delay); | 112 loss_detection_timeout_ = it->sent_time.Add(loss_delay); |
98 break; | 113 break; |
99 } | 114 } |
100 } | 115 } |
101 } | 116 } |
102 } | 117 } |
103 | 118 |
104 QuicTime GeneralLossAlgorithm::GetLossTimeout() const { | 119 QuicTime GeneralLossAlgorithm::GetLossTimeout() const { |
105 return loss_detection_timeout_; | 120 return loss_detection_timeout_; |
106 } | 121 } |
107 | 122 |
108 } // namespace net | 123 } // namespace net |
OLD | NEW |