| 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" |
| 11 #include "net/quic/congestion_control/receive_algorithm_interface.h" | 11 #include "net/quic/congestion_control/receive_algorithm_interface.h" |
| 12 #include "net/quic/congestion_control/send_algorithm_interface.h" | 12 #include "net/quic/congestion_control/send_algorithm_interface.h" |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 const int kBitrateSmoothingPeriodMs = 3000; | 15 const int kBitrateSmoothingPeriodMs = 1000; |
| 16 const int kMinBitrateSmoothingPeriodMs = 500; | 16 const int kMinBitrateSmoothingPeriodMs = 500; |
| 17 const int kHistoryPeriodMs = 5000; | 17 const int kHistoryPeriodMs = 5000; |
| 18 | 18 |
| 19 const int kDefaultRetransmissionTimeMs = 500; | 19 const int kDefaultRetransmissionTimeMs = 500; |
| 20 const size_t kMaxRetransmissions = 15; | 20 const size_t kMaxRetransmissions = 10; |
| 21 const size_t kTailDropWindowSize = 5; |
| 21 | 22 |
| 22 COMPILE_ASSERT(kHistoryPeriodMs >= kBitrateSmoothingPeriodMs, | 23 COMPILE_ASSERT(kHistoryPeriodMs >= kBitrateSmoothingPeriodMs, |
| 23 history_must_be_longer_or_equal_to_the_smoothing_period); | 24 history_must_be_longer_or_equal_to_the_smoothing_period); |
| 24 } // namespace | 25 } // namespace |
| 25 | 26 |
| 26 using std::map; | 27 using std::map; |
| 27 using std::min; | 28 using std::min; |
| 28 | 29 |
| 29 namespace net { | 30 namespace net { |
| 30 | 31 |
| 31 QuicCongestionManager::QuicCongestionManager( | 32 QuicCongestionManager::QuicCongestionManager( |
| 32 const QuicClock* clock, | 33 const QuicClock* clock, |
| 33 CongestionFeedbackType type) | 34 CongestionFeedbackType type) |
| 34 : clock_(clock), | 35 : clock_(clock), |
| 35 receive_algorithm_(ReceiveAlgorithmInterface::Create(clock, type)), | 36 receive_algorithm_(ReceiveAlgorithmInterface::Create(clock, type)), |
| 36 send_algorithm_(SendAlgorithmInterface::Create(clock, type)) { | 37 send_algorithm_(SendAlgorithmInterface::Create(clock, type)), |
| 38 largest_missing_(0) { |
| 37 } | 39 } |
| 38 | 40 |
| 39 QuicCongestionManager::~QuicCongestionManager() { | 41 QuicCongestionManager::~QuicCongestionManager() { |
| 40 STLDeleteValues(&packet_history_map_); | 42 STLDeleteValues(&packet_history_map_); |
| 41 } | 43 } |
| 42 | 44 |
| 43 void QuicCongestionManager::SentPacket(QuicPacketSequenceNumber sequence_number, | 45 void QuicCongestionManager::SentPacket(QuicPacketSequenceNumber sequence_number, |
| 46 QuicTime sent_time, |
| 44 QuicByteCount bytes, | 47 QuicByteCount bytes, |
| 45 bool is_retransmission) { | 48 bool is_retransmission) { |
| 46 DCHECK(!ContainsKey(pending_packets_, sequence_number)); | 49 DCHECK(!ContainsKey(pending_packets_, sequence_number)); |
| 47 send_algorithm_->SentPacket(sequence_number, bytes, is_retransmission); | 50 send_algorithm_->SentPacket(sent_time, sequence_number, bytes, |
| 51 is_retransmission); |
| 48 | 52 |
| 49 packet_history_map_[sequence_number] = | 53 packet_history_map_[sequence_number] = |
| 50 new class SendAlgorithmInterface::SentPacket(bytes, clock_->Now()); | 54 new class SendAlgorithmInterface::SentPacket(bytes, sent_time); |
| 51 pending_packets_[sequence_number] = bytes; | 55 pending_packets_[sequence_number] = bytes; |
| 52 CleanupPacketHistory(); | 56 CleanupPacketHistory(); |
| 53 DLOG(INFO) << "Sent sequence number:" << sequence_number; | |
| 54 } | 57 } |
| 55 | 58 |
| 56 void QuicCongestionManager::OnIncomingQuicCongestionFeedbackFrame( | 59 void QuicCongestionManager::OnIncomingQuicCongestionFeedbackFrame( |
| 57 const QuicCongestionFeedbackFrame& frame) { | 60 const QuicCongestionFeedbackFrame& frame, QuicTime feedback_receive_time) { |
| 58 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame(frame, | 61 QuicBandwidth sent_bandwidth = SentBandwidth(feedback_receive_time); |
| 59 packet_history_map_); | 62 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame( |
| 63 frame, feedback_receive_time, sent_bandwidth, packet_history_map_); |
| 60 } | 64 } |
| 61 | 65 |
| 62 void QuicCongestionManager::OnIncomingAckFrame(const QuicAckFrame& frame) { | 66 void QuicCongestionManager::OnIncomingAckFrame(const QuicAckFrame& frame, |
| 67 QuicTime ack_receive_time) { |
| 63 // We calculate the RTT based on the highest ACKed sequence number, the lower | 68 // We calculate the RTT based on the highest ACKed sequence number, the lower |
| 64 // sequence numbers will include the ACK aggregation delay. | 69 // sequence numbers will include the ACK aggregation delay. |
| 65 QuicTime::Delta rtt = QuicTime::Delta::Zero(); | 70 QuicTime::Delta rtt = QuicTime::Delta::Zero(); |
| 66 SendAlgorithmInterface::SentPacketsMap::iterator history_it = | 71 SendAlgorithmInterface::SentPacketsMap::iterator history_it = |
| 67 packet_history_map_.find(frame.received_info.largest_observed); | 72 packet_history_map_.find(frame.received_info.largest_observed); |
| 68 if (history_it != packet_history_map_.end()) { | 73 if (history_it != packet_history_map_.end()) { |
| 69 rtt = clock_->Now().Subtract(history_it->second->SendTimestamp()); | 74 // TODO(pwestin): we need to add the delta to the feedback message. |
| 75 rtt = ack_receive_time.Subtract(history_it->second->SendTimestamp()); |
| 70 } | 76 } |
| 71 // We want to. | 77 // We want to. |
| 72 // * Get all packets lower(including) than largest_observed | 78 // * Get all packets lower(including) than largest_observed |
| 73 // from pending_packets_. | 79 // from pending_packets_. |
| 74 // * Remove all missing packets. | 80 // * Remove all missing packets. |
| 75 // * Send each ACK in the list to send_algorithm_. | 81 // * Send each ACK in the list to send_algorithm_. |
| 76 PendingPacketsMap::iterator it, it_upper; | 82 PendingPacketsMap::iterator it, it_upper; |
| 77 it = pending_packets_.begin(); | 83 it = pending_packets_.begin(); |
| 78 it_upper = pending_packets_.upper_bound(frame.received_info.largest_observed); | 84 it_upper = pending_packets_.upper_bound(frame.received_info.largest_observed); |
| 79 | 85 |
| 86 bool new_packet_loss_reported = false; |
| 80 while (it != it_upper) { | 87 while (it != it_upper) { |
| 81 QuicPacketSequenceNumber sequence_number = it->first; | 88 QuicPacketSequenceNumber sequence_number = it->first; |
| 82 if (!frame.received_info.IsAwaitingPacket(sequence_number)) { | 89 if (!IsAwaitingPacket(frame.received_info, sequence_number)) { |
| 83 // Not missing, hence implicitly acked. | 90 // Not missing, hence implicitly acked. |
| 84 send_algorithm_->OnIncomingAck(sequence_number, | 91 send_algorithm_->OnIncomingAck(sequence_number, |
| 85 it->second, | 92 it->second, |
| 86 rtt); | 93 rtt); |
| 87 DLOG(INFO) << "ACKed sequence number:" << sequence_number; | |
| 88 pending_packets_.erase(it++); // Must be incremented post to work. | 94 pending_packets_.erase(it++); // Must be incremented post to work. |
| 89 } else { | 95 } else { |
| 96 if (sequence_number > largest_missing_) { |
| 97 // We have a new loss reported. |
| 98 new_packet_loss_reported = true; |
| 99 largest_missing_ = sequence_number; |
| 100 } |
| 90 ++it; | 101 ++it; |
| 91 } | 102 } |
| 92 } | 103 } |
| 104 if (new_packet_loss_reported) { |
| 105 send_algorithm_->OnIncomingLoss(ack_receive_time); |
| 106 } |
| 93 } | 107 } |
| 94 | 108 |
| 95 QuicTime::Delta QuicCongestionManager::TimeUntilSend(bool is_retransmission) { | 109 QuicTime::Delta QuicCongestionManager::TimeUntilSend(QuicTime now, |
| 96 return send_algorithm_->TimeUntilSend(is_retransmission); | 110 bool is_retransmission) { |
| 111 return send_algorithm_->TimeUntilSend(now, is_retransmission); |
| 97 } | 112 } |
| 98 | 113 |
| 99 bool QuicCongestionManager::GenerateCongestionFeedback( | 114 bool QuicCongestionManager::GenerateCongestionFeedback( |
| 100 QuicCongestionFeedbackFrame* feedback) { | 115 QuicCongestionFeedbackFrame* feedback) { |
| 101 return receive_algorithm_->GenerateCongestionFeedback(feedback); | 116 return receive_algorithm_->GenerateCongestionFeedback(feedback); |
| 102 } | 117 } |
| 103 | 118 |
| 104 void QuicCongestionManager::RecordIncomingPacket( | 119 void QuicCongestionManager::RecordIncomingPacket( |
| 105 QuicByteCount bytes, | 120 QuicByteCount bytes, |
| 106 QuicPacketSequenceNumber sequence_number, | 121 QuicPacketSequenceNumber sequence_number, |
| 107 QuicTime timestamp, | 122 QuicTime timestamp, |
| 108 bool revived) { | 123 bool revived) { |
| 109 receive_algorithm_->RecordIncomingPacket(bytes, sequence_number, timestamp, | 124 receive_algorithm_->RecordIncomingPacket(bytes, sequence_number, timestamp, |
| 110 revived); | 125 revived); |
| 111 } | 126 } |
| 112 | 127 |
| 113 // static | 128 // static |
| 114 const QuicTime::Delta QuicCongestionManager::DefaultRetransmissionTime() { | 129 const QuicTime::Delta QuicCongestionManager::DefaultRetransmissionTime() { |
| 115 return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); | 130 return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); |
| 116 } | 131 } |
| 117 | 132 |
| 118 // static | 133 // static |
| 119 const QuicTime::Delta QuicCongestionManager::GetRetransmissionDelay( | 134 const QuicTime::Delta QuicCongestionManager::GetRetransmissionDelay( |
| 135 size_t unacked_packets_count, |
| 120 size_t number_retransmissions) { | 136 size_t number_retransmissions) { |
| 137 if (unacked_packets_count <= kTailDropWindowSize) { |
| 138 return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); |
| 139 } |
| 140 |
| 121 return QuicTime::Delta::FromMilliseconds( | 141 return QuicTime::Delta::FromMilliseconds( |
| 122 kDefaultRetransmissionTimeMs * | 142 kDefaultRetransmissionTimeMs * |
| 123 (1 << min<size_t>(number_retransmissions, kMaxRetransmissions))); | 143 (1 << min<size_t>(number_retransmissions, kMaxRetransmissions))); |
| 124 } | 144 } |
| 125 | 145 |
| 126 QuicBandwidth QuicCongestionManager::SentBandwidth() const { | 146 QuicBandwidth QuicCongestionManager::SentBandwidth( |
| 147 QuicTime feedback_receive_time) const { |
| 127 const QuicTime::Delta kBitrateSmoothingPeriod = | 148 const QuicTime::Delta kBitrateSmoothingPeriod = |
| 128 QuicTime::Delta::FromMilliseconds(kBitrateSmoothingPeriodMs); | 149 QuicTime::Delta::FromMilliseconds(kBitrateSmoothingPeriodMs); |
| 129 const QuicTime::Delta kMinBitrateSmoothingPeriod = | 150 const QuicTime::Delta kMinBitrateSmoothingPeriod = |
| 130 QuicTime::Delta::FromMilliseconds(kMinBitrateSmoothingPeriodMs); | 151 QuicTime::Delta::FromMilliseconds(kMinBitrateSmoothingPeriodMs); |
| 131 | 152 |
| 132 QuicTime now = clock_->Now(); | |
| 133 QuicByteCount sum_bytes_sent = 0; | 153 QuicByteCount sum_bytes_sent = 0; |
| 134 | 154 |
| 135 // Sum packet from new until they are kBitrateSmoothingPeriod old. | 155 // Sum packet from new until they are kBitrateSmoothingPeriod old. |
| 136 SendAlgorithmInterface::SentPacketsMap::const_reverse_iterator history_rit = | 156 SendAlgorithmInterface::SentPacketsMap::const_reverse_iterator history_rit = |
| 137 packet_history_map_.rbegin(); | 157 packet_history_map_.rbegin(); |
| 138 | 158 |
| 139 QuicTime::Delta max_diff = QuicTime::Delta::Zero(); | 159 QuicTime::Delta max_diff = QuicTime::Delta::Zero(); |
| 140 for (; history_rit != packet_history_map_.rend(); ++history_rit) { | 160 for (; history_rit != packet_history_map_.rend(); ++history_rit) { |
| 141 QuicTime::Delta diff = now.Subtract(history_rit->second->SendTimestamp()); | 161 QuicTime::Delta diff = |
| 162 feedback_receive_time.Subtract(history_rit->second->SendTimestamp()); |
| 142 if (diff > kBitrateSmoothingPeriod) { | 163 if (diff > kBitrateSmoothingPeriod) { |
| 143 break; | 164 break; |
| 144 } | 165 } |
| 145 sum_bytes_sent += history_rit->second->BytesSent(); | 166 sum_bytes_sent += history_rit->second->BytesSent(); |
| 146 max_diff = diff; | 167 max_diff = diff; |
| 147 } | 168 } |
| 148 if (max_diff < kMinBitrateSmoothingPeriod) { | 169 if (max_diff < kMinBitrateSmoothingPeriod) { |
| 149 // No estimate. | 170 // No estimate. |
| 150 return QuicBandwidth::Zero(); | 171 return QuicBandwidth::Zero(); |
| 151 } | 172 } |
| 152 return QuicBandwidth::FromBytesAndTimeDelta(sum_bytes_sent, max_diff); | 173 return QuicBandwidth::FromBytesAndTimeDelta(sum_bytes_sent, max_diff); |
| 153 } | 174 } |
| 154 | 175 |
| 155 QuicBandwidth QuicCongestionManager::BandwidthEstimate() { | 176 QuicBandwidth QuicCongestionManager::BandwidthEstimate() { |
| 156 return send_algorithm_->BandwidthEstimate(); | 177 return send_algorithm_->BandwidthEstimate(); |
| 157 } | 178 } |
| 158 | 179 |
| 159 void QuicCongestionManager::CleanupPacketHistory() { | 180 void QuicCongestionManager::CleanupPacketHistory() { |
| 160 const QuicTime::Delta kHistoryPeriod = | 181 const QuicTime::Delta kHistoryPeriod = |
| 161 QuicTime::Delta::FromMilliseconds(kHistoryPeriodMs); | 182 QuicTime::Delta::FromMilliseconds(kHistoryPeriodMs); |
| 162 QuicTime Now = clock_->Now(); | 183 QuicTime now = clock_->ApproximateNow(); |
| 163 | 184 |
| 164 SendAlgorithmInterface::SentPacketsMap::iterator history_it = | 185 SendAlgorithmInterface::SentPacketsMap::iterator history_it = |
| 165 packet_history_map_.begin(); | 186 packet_history_map_.begin(); |
| 166 for (; history_it != packet_history_map_.end(); ++history_it) { | 187 for (; history_it != packet_history_map_.end(); ++history_it) { |
| 167 if (Now.Subtract(history_it->second->SendTimestamp()) <= kHistoryPeriod) { | 188 if (now.Subtract(history_it->second->SendTimestamp()) <= kHistoryPeriod) { |
| 168 return; | 189 return; |
| 169 } | 190 } |
| 170 DLOG(INFO) << "Clear sequence number:" << history_it->first | |
| 171 << "from history"; | |
| 172 delete history_it->second; | 191 delete history_it->second; |
| 173 packet_history_map_.erase(history_it); | 192 packet_history_map_.erase(history_it); |
| 174 history_it = packet_history_map_.begin(); | 193 history_it = packet_history_map_.begin(); |
| 175 } | 194 } |
| 176 } | 195 } |
| 177 | 196 |
| 178 } // namespace net | 197 } // namespace net |
| OLD | NEW |