OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/quic_congestion_manager.h" | 5 #include "net/quic/congestion_control/quic_congestion_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 namespace net { | 35 namespace net { |
36 | 36 |
37 QuicCongestionManager::QuicCongestionManager( | 37 QuicCongestionManager::QuicCongestionManager( |
38 const QuicClock* clock, | 38 const QuicClock* clock, |
39 CongestionFeedbackType type) | 39 CongestionFeedbackType type) |
40 : clock_(clock), | 40 : clock_(clock), |
41 receive_algorithm_(ReceiveAlgorithmInterface::Create(clock, type)), | 41 receive_algorithm_(ReceiveAlgorithmInterface::Create(clock, type)), |
42 send_algorithm_(SendAlgorithmInterface::Create(clock, type)), | 42 send_algorithm_(SendAlgorithmInterface::Create(clock, type)), |
43 largest_missing_(0), | 43 largest_missing_(0), |
44 current_rtt_(QuicTime::Delta::Infinite()) { | 44 rtt_sample_(QuicTime::Delta::Infinite()) { |
45 } | 45 } |
46 | 46 |
47 QuicCongestionManager::~QuicCongestionManager() { | 47 QuicCongestionManager::~QuicCongestionManager() { |
48 STLDeleteValues(&packet_history_map_); | 48 STLDeleteValues(&packet_history_map_); |
49 } | 49 } |
50 | 50 |
51 void QuicCongestionManager::SetFromConfig(const QuicConfig& config, | 51 void QuicCongestionManager::SetFromConfig(const QuicConfig& config, |
52 bool is_server) { | 52 bool is_server) { |
53 if (config.initial_round_trip_time_us() > 0 && | 53 if (config.initial_round_trip_time_us() > 0 && |
54 current_rtt_.IsInfinite()) { | 54 rtt_sample_.IsInfinite()) { |
55 // The initial rtt should already be set on the client side. | 55 // The initial rtt should already be set on the client side. |
56 DLOG_IF(INFO, !is_server) | 56 DLOG_IF(INFO, !is_server) |
57 << "Client did not set an initial RTT, but did negotiate one."; | 57 << "Client did not set an initial RTT, but did negotiate one."; |
58 current_rtt_ = | 58 rtt_sample_ = |
59 QuicTime::Delta::FromMicroseconds(config.initial_round_trip_time_us()); | 59 QuicTime::Delta::FromMicroseconds(config.initial_round_trip_time_us()); |
60 } | 60 } |
61 send_algorithm_->SetFromConfig(config, is_server); | 61 send_algorithm_->SetFromConfig(config, is_server); |
62 } | 62 } |
63 | 63 |
64 void QuicCongestionManager::OnPacketSent( | 64 void QuicCongestionManager::OnPacketSent( |
65 QuicPacketSequenceNumber sequence_number, | 65 QuicPacketSequenceNumber sequence_number, |
66 QuicTime sent_time, | 66 QuicTime sent_time, |
67 QuicByteCount bytes, | 67 QuicByteCount bytes, |
68 TransmissionType transmission_type, | 68 TransmissionType transmission_type, |
(...skipping 27 matching lines...) Expand all Loading... |
96 frame, feedback_receive_time, packet_history_map_); | 96 frame, feedback_receive_time, packet_history_map_); |
97 } | 97 } |
98 | 98 |
99 void QuicCongestionManager::OnIncomingAckFrame(const QuicAckFrame& frame, | 99 void QuicCongestionManager::OnIncomingAckFrame(const QuicAckFrame& frame, |
100 QuicTime ack_receive_time) { | 100 QuicTime ack_receive_time) { |
101 // We calculate the RTT based on the highest ACKed sequence number, the lower | 101 // We calculate the RTT based on the highest ACKed sequence number, the lower |
102 // sequence numbers will include the ACK aggregation delay. | 102 // sequence numbers will include the ACK aggregation delay. |
103 SendAlgorithmInterface::SentPacketsMap::iterator history_it = | 103 SendAlgorithmInterface::SentPacketsMap::iterator history_it = |
104 packet_history_map_.find(frame.received_info.largest_observed); | 104 packet_history_map_.find(frame.received_info.largest_observed); |
105 // TODO(satyamshekhar): largest_observed might be missing. | 105 // TODO(satyamshekhar): largest_observed might be missing. |
106 if (history_it != packet_history_map_.end() && | 106 if (history_it != packet_history_map_.end()) { |
107 !frame.received_info.delta_time_largest_observed.IsInfinite()) { | |
108 QuicTime::Delta send_delta = ack_receive_time.Subtract( | 107 QuicTime::Delta send_delta = ack_receive_time.Subtract( |
109 history_it->second->SendTimestamp()); | 108 history_it->second->SendTimestamp()); |
110 if (send_delta > frame.received_info.delta_time_largest_observed) { | 109 if (send_delta > frame.received_info.delta_time_largest_observed) { |
111 current_rtt_ = send_delta.Subtract( | 110 rtt_sample_ = send_delta.Subtract( |
112 frame.received_info.delta_time_largest_observed); | 111 frame.received_info.delta_time_largest_observed); |
| 112 } else if (rtt_sample_.IsInfinite()) { |
| 113 // Even though we received information from the peer suggesting |
| 114 // an invalid (negative) RTT, we can use the send delta as an |
| 115 // approximation until we get a better estimate. |
| 116 rtt_sample_ = send_delta; |
113 } | 117 } |
114 } | 118 } |
115 // We want to. | 119 // We want to. |
116 // * Get all packets lower(including) than largest_observed | 120 // * Get all packets lower(including) than largest_observed |
117 // from pending_packets_. | 121 // from pending_packets_. |
118 // * Remove all missing packets. | 122 // * Remove all missing packets. |
119 // * Send each ACK in the list to send_algorithm_. | 123 // * Send each ACK in the list to send_algorithm_. |
120 PendingPacketsMap::iterator it, it_upper; | 124 PendingPacketsMap::iterator it, it_upper; |
121 it = pending_packets_.begin(); | 125 it = pending_packets_.begin(); |
122 it_upper = pending_packets_.upper_bound(frame.received_info.largest_observed); | 126 it_upper = pending_packets_.upper_bound(frame.received_info.largest_observed); |
123 | 127 |
124 bool new_packet_loss_reported = false; | 128 bool new_packet_loss_reported = false; |
125 while (it != it_upper) { | 129 while (it != it_upper) { |
126 QuicPacketSequenceNumber sequence_number = it->first; | 130 QuicPacketSequenceNumber sequence_number = it->first; |
127 if (!IsAwaitingPacket(frame.received_info, sequence_number)) { | 131 if (!IsAwaitingPacket(frame.received_info, sequence_number)) { |
128 // Not missing, hence implicitly acked. | 132 // Not missing, hence implicitly acked. |
129 send_algorithm_->OnIncomingAck(sequence_number, it->second, current_rtt_); | 133 send_algorithm_->OnIncomingAck(sequence_number, it->second, rtt_sample_); |
130 pending_packets_.erase(it++); // Must be incremented post to work. | 134 pending_packets_.erase(it++); // Must be incremented post to work. |
131 } else { | 135 } else { |
132 if (sequence_number > largest_missing_) { | 136 if (sequence_number > largest_missing_) { |
133 // We have a new loss reported. | 137 // We have a new loss reported. |
134 new_packet_loss_reported = true; | 138 new_packet_loss_reported = true; |
135 largest_missing_ = sequence_number; | 139 largest_missing_ = sequence_number; |
136 } | 140 } |
137 ++it; | 141 ++it; |
138 } | 142 } |
139 } | 143 } |
(...skipping 24 matching lines...) Expand all Loading... |
164 | 168 |
165 void QuicCongestionManager::RecordIncomingPacket( | 169 void QuicCongestionManager::RecordIncomingPacket( |
166 QuicByteCount bytes, | 170 QuicByteCount bytes, |
167 QuicPacketSequenceNumber sequence_number, | 171 QuicPacketSequenceNumber sequence_number, |
168 QuicTime timestamp, | 172 QuicTime timestamp, |
169 bool revived) { | 173 bool revived) { |
170 receive_algorithm_->RecordIncomingPacket(bytes, sequence_number, timestamp, | 174 receive_algorithm_->RecordIncomingPacket(bytes, sequence_number, timestamp, |
171 revived); | 175 revived); |
172 } | 176 } |
173 | 177 |
174 const QuicTime::Delta QuicCongestionManager::rtt() { | |
175 return current_rtt_; | |
176 } | |
177 | |
178 const QuicTime::Delta QuicCongestionManager::DefaultRetransmissionTime() { | 178 const QuicTime::Delta QuicCongestionManager::DefaultRetransmissionTime() { |
179 return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); | 179 return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); |
180 } | 180 } |
181 | 181 |
182 // Ensures that the Delayed Ack timer is always set to a value lesser | 182 // Ensures that the Delayed Ack timer is always set to a value lesser |
183 // than the retransmission timer's minimum value (MinRTO). We want the | 183 // than the retransmission timer's minimum value (MinRTO). We want the |
184 // delayed ack to get back to the QUIC peer before the sender's | 184 // delayed ack to get back to the QUIC peer before the sender's |
185 // retransmission timer triggers. Since we do not know the | 185 // retransmission timer triggers. Since we do not know the |
186 // reverse-path one-way delay, we assume equal delays for forward and | 186 // reverse-path one-way delay, we assume equal delays for forward and |
187 // reverse paths, and ensure that the timer is set to less than half | 187 // reverse paths, and ensure that the timer is set to less than half |
188 // of the MinRTO. | 188 // of the MinRTO. |
189 // There may be a value in making this delay adaptive with the help of | 189 // There may be a value in making this delay adaptive with the help of |
190 // the sender and a signaling mechanism -- if the sender uses a | 190 // the sender and a signaling mechanism -- if the sender uses a |
191 // different MinRTO, we may get spurious retransmissions. May not have | 191 // different MinRTO, we may get spurious retransmissions. May not have |
192 // any benefits, but if the delayed ack becomes a significant source | 192 // any benefits, but if the delayed ack becomes a significant source |
193 // of (likely, tail) latency, then consider such a mechanism. | 193 // of (likely, tail) latency, then consider such a mechanism. |
194 | 194 |
195 const QuicTime::Delta QuicCongestionManager::DelayedAckTime() { | 195 const QuicTime::Delta QuicCongestionManager::DelayedAckTime() { |
196 return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2); | 196 return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2); |
197 } | 197 } |
198 | 198 |
199 const QuicTime::Delta QuicCongestionManager::GetRetransmissionDelay( | 199 const QuicTime::Delta QuicCongestionManager::GetRetransmissionDelay( |
200 size_t unacked_packets_count, | 200 size_t unacked_packets_count, |
201 size_t number_retransmissions) const { | 201 size_t number_retransmissions) const { |
| 202 if (unacked_packets_count <= kTailDropWindowSize) { |
| 203 // Avoid exponential backoff of RTO when there are only a few packets |
| 204 // outstanding. This helps avoid the situation where fake packet loss |
| 205 // causes a packet and it's retransmission to be dropped causing |
| 206 // test timouts. |
| 207 if (number_retransmissions <= kTailDropMaxRetransmissions) { |
| 208 number_retransmissions = 0; |
| 209 } else { |
| 210 number_retransmissions -= kTailDropMaxRetransmissions; |
| 211 } |
| 212 } |
| 213 |
202 QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay(); | 214 QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay(); |
203 if (retransmission_delay.IsZero()) { | 215 if (retransmission_delay.IsZero()) { |
204 // We are in the initial state, use default timeout values. | 216 // We are in the initial state, use default timeout values. |
205 if (unacked_packets_count <= kTailDropWindowSize) { | |
206 if (number_retransmissions <= kTailDropMaxRetransmissions) { | |
207 return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); | |
208 } | |
209 number_retransmissions -= kTailDropMaxRetransmissions; | |
210 } | |
211 retransmission_delay = | 217 retransmission_delay = |
212 QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); | 218 QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); |
213 } | 219 } |
214 // Calculate exponential back off. | 220 // Calculate exponential back off. |
215 retransmission_delay = QuicTime::Delta::FromMilliseconds( | 221 retransmission_delay = QuicTime::Delta::FromMilliseconds( |
216 retransmission_delay.ToMilliseconds() * static_cast<size_t>( | 222 retransmission_delay.ToMilliseconds() * static_cast<size_t>( |
217 (1 << min<size_t>(number_retransmissions, kMaxRetransmissions)))); | 223 (1 << min<size_t>(number_retransmissions, kMaxRetransmissions)))); |
218 | 224 |
219 // TODO(rch): This code should move to |send_algorithm_|. | 225 // TODO(rch): This code should move to |send_algorithm_|. |
220 if (retransmission_delay.ToMilliseconds() < kMinRetransmissionTimeMs) { | 226 if (retransmission_delay.ToMilliseconds() < kMinRetransmissionTimeMs) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 if (now.Subtract(history_it->second->SendTimestamp()) <= kHistoryPeriod) { | 259 if (now.Subtract(history_it->second->SendTimestamp()) <= kHistoryPeriod) { |
254 return; | 260 return; |
255 } | 261 } |
256 delete history_it->second; | 262 delete history_it->second; |
257 packet_history_map_.erase(history_it); | 263 packet_history_map_.erase(history_it); |
258 history_it = packet_history_map_.begin(); | 264 history_it = packet_history_map_.begin(); |
259 } | 265 } |
260 } | 266 } |
261 | 267 |
262 } // namespace net | 268 } // namespace net |
OLD | NEW |