| 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 |