OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/quic_sent_packet_manager.h" | 5 #include "net/quic/quic_sent_packet_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 n_connection_simulation_(false), | 93 n_connection_simulation_(false), |
94 receive_buffer_bytes_(kDefaultSocketReceiveBuffer), | 94 receive_buffer_bytes_(kDefaultSocketReceiveBuffer), |
95 least_packet_awaited_by_peer_(1), | 95 least_packet_awaited_by_peer_(1), |
96 first_rto_transmission_(0), | 96 first_rto_transmission_(0), |
97 consecutive_rto_count_(0), | 97 consecutive_rto_count_(0), |
98 consecutive_tlp_count_(0), | 98 consecutive_tlp_count_(0), |
99 consecutive_crypto_retransmission_count_(0), | 99 consecutive_crypto_retransmission_count_(0), |
100 pending_timer_transmission_count_(0), | 100 pending_timer_transmission_count_(0), |
101 max_tail_loss_probes_(kDefaultMaxTailLossProbes), | 101 max_tail_loss_probes_(kDefaultMaxTailLossProbes), |
102 using_pacing_(false), | 102 using_pacing_(false), |
| 103 use_new_rto_(false), |
103 handshake_confirmed_(false) { | 104 handshake_confirmed_(false) { |
104 } | 105 } |
105 | 106 |
106 QuicSentPacketManager::~QuicSentPacketManager() { | 107 QuicSentPacketManager::~QuicSentPacketManager() { |
107 } | 108 } |
108 | 109 |
109 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { | 110 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { |
110 if (config.HasReceivedInitialRoundTripTimeUs() && | 111 if (config.HasReceivedInitialRoundTripTimeUs() && |
111 config.ReceivedInitialRoundTripTimeUs() > 0) { | 112 config.ReceivedInitialRoundTripTimeUs() > 0) { |
112 rtt_stats_.set_initial_rtt_us( | 113 rtt_stats_.set_initial_rtt_us( |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 } | 148 } |
148 if (HasClientSentConnectionOption(config, k1CON)) { | 149 if (HasClientSentConnectionOption(config, k1CON)) { |
149 send_algorithm_->SetNumEmulatedConnections(1); | 150 send_algorithm_->SetNumEmulatedConnections(1); |
150 } | 151 } |
151 if (HasClientSentConnectionOption(config, kNCON)) { | 152 if (HasClientSentConnectionOption(config, kNCON)) { |
152 n_connection_simulation_ = true; | 153 n_connection_simulation_ = true; |
153 } | 154 } |
154 if (HasClientSentConnectionOption(config, kNTLP)) { | 155 if (HasClientSentConnectionOption(config, kNTLP)) { |
155 max_tail_loss_probes_ = 0; | 156 max_tail_loss_probes_ = 0; |
156 } | 157 } |
| 158 if (HasClientSentConnectionOption(config, kNRTO)) { |
| 159 use_new_rto_ = true; |
| 160 } |
157 if (config.HasReceivedConnectionOptions() && | 161 if (config.HasReceivedConnectionOptions() && |
158 ContainsQuicTag(config.ReceivedConnectionOptions(), kTIME)) { | 162 ContainsQuicTag(config.ReceivedConnectionOptions(), kTIME)) { |
159 loss_algorithm_.reset(LossDetectionInterface::Create(kTime)); | 163 loss_algorithm_.reset(LossDetectionInterface::Create(kTime)); |
160 } | 164 } |
161 if (config.HasReceivedSocketReceiveBuffer()) { | 165 if (config.HasReceivedSocketReceiveBuffer()) { |
162 receive_buffer_bytes_ = | 166 receive_buffer_bytes_ = |
163 max(kMinSocketReceiveBuffer, | 167 max(kMinSocketReceiveBuffer, |
164 static_cast<QuicByteCount>(config.ReceivedSocketReceiveBuffer())); | 168 static_cast<QuicByteCount>(config.ReceivedSocketReceiveBuffer())); |
165 } | 169 } |
166 send_algorithm_->SetFromConfig(config, is_server_, using_pacing_); | 170 send_algorithm_->SetFromConfig(config, is_server_, using_pacing_); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 QuicTime ack_receive_time) { | 212 QuicTime ack_receive_time) { |
209 QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight(); | 213 QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight(); |
210 | 214 |
211 UpdatePacketInformationReceivedByPeer(ack_frame); | 215 UpdatePacketInformationReceivedByPeer(ack_frame); |
212 bool rtt_updated = MaybeUpdateRTT(ack_frame, ack_receive_time); | 216 bool rtt_updated = MaybeUpdateRTT(ack_frame, ack_receive_time); |
213 DCHECK_GE(ack_frame.largest_observed, unacked_packets_.largest_observed()); | 217 DCHECK_GE(ack_frame.largest_observed, unacked_packets_.largest_observed()); |
214 unacked_packets_.IncreaseLargestObserved(ack_frame.largest_observed); | 218 unacked_packets_.IncreaseLargestObserved(ack_frame.largest_observed); |
215 | 219 |
216 HandleAckForSentPackets(ack_frame); | 220 HandleAckForSentPackets(ack_frame); |
217 InvokeLossDetection(ack_receive_time); | 221 InvokeLossDetection(ack_receive_time); |
| 222 // Ignore losses in RTO mode. |
| 223 if (FLAGS_quic_use_new_rto && consecutive_rto_count_ > 0 && !use_new_rto_) { |
| 224 packets_lost_.clear(); |
| 225 } |
218 MaybeInvokeCongestionEvent(rtt_updated, bytes_in_flight); | 226 MaybeInvokeCongestionEvent(rtt_updated, bytes_in_flight); |
219 unacked_packets_.RemoveObsoletePackets(); | 227 unacked_packets_.RemoveObsoletePackets(); |
220 | 228 |
221 sustained_bandwidth_recorder_.RecordEstimate( | 229 sustained_bandwidth_recorder_.RecordEstimate( |
222 send_algorithm_->InRecovery(), | 230 send_algorithm_->InRecovery(), |
223 send_algorithm_->InSlowStart(), | 231 send_algorithm_->InSlowStart(), |
224 send_algorithm_->BandwidthEstimate(), | 232 send_algorithm_->BandwidthEstimate(), |
225 ack_receive_time, | 233 ack_receive_time, |
226 clock_->WallNow(), | 234 clock_->WallNow(), |
227 rtt_stats_.smoothed_rtt()); | 235 rtt_stats_.smoothed_rtt()); |
228 | 236 |
229 // If we have received a truncated ack, then we need to clear out some | 237 // If we have received a truncated ack, then we need to clear out some |
230 // previous transmissions to allow the peer to actually ACK new packets. | 238 // previous transmissions to allow the peer to actually ACK new packets. |
231 if (ack_frame.is_truncated) { | 239 if (ack_frame.is_truncated) { |
232 unacked_packets_.ClearAllPreviousRetransmissions(); | 240 unacked_packets_.ClearAllPreviousRetransmissions(); |
233 } | 241 } |
234 | 242 |
235 // Anytime we are making forward progress and have a new RTT estimate, reset | 243 // Anytime we are making forward progress and have a new RTT estimate, reset |
236 // the backoff counters. | 244 // the backoff counters. |
237 if (rtt_updated) { | 245 if (rtt_updated) { |
238 if (FLAGS_quic_use_new_rto && consecutive_rto_count_ > 0) { | 246 if (FLAGS_quic_use_new_rto && consecutive_rto_count_ > 0) { |
239 // If the ack acknowledges data sent prior to the RTO, | 247 // If the ack acknowledges data sent prior to the RTO, |
240 // the RTO was spurious. | 248 // the RTO was spurious. |
241 if (ack_frame.largest_observed < first_rto_transmission_) { | 249 if (ack_frame.largest_observed < first_rto_transmission_) { |
242 // Replace SRTT with latest_rtt and increase the variance to prevent | 250 // Replace SRTT with latest_rtt and increase the variance to prevent |
243 // a spurious RTO from happening again. | 251 // a spurious RTO from happening again. |
244 rtt_stats_.ExpireSmoothedMetrics(); | 252 rtt_stats_.ExpireSmoothedMetrics(); |
245 } else { | 253 } else { |
246 send_algorithm_->OnRetransmissionTimeout(true); | 254 if (!use_new_rto_) { |
| 255 send_algorithm_->OnRetransmissionTimeout(true); |
| 256 } |
247 } | 257 } |
248 } | 258 } |
249 // Reset all retransmit counters any time a new packet is acked. | 259 // Reset all retransmit counters any time a new packet is acked. |
250 consecutive_rto_count_ = 0; | 260 consecutive_rto_count_ = 0; |
251 consecutive_tlp_count_ = 0; | 261 consecutive_tlp_count_ = 0; |
252 consecutive_crypto_retransmission_count_ = 0; | 262 consecutive_crypto_retransmission_count_ = 0; |
253 } | 263 } |
254 | 264 |
255 if (debug_delegate_ != nullptr) { | 265 if (debug_delegate_ != nullptr) { |
256 debug_delegate_->OnIncomingAck(ack_frame, ack_receive_time, | 266 debug_delegate_->OnIncomingAck(ack_frame, ack_receive_time, |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 } else { | 569 } else { |
560 PendingRetransmissionMap::iterator it = | 570 PendingRetransmissionMap::iterator it = |
561 pending_retransmissions_.find(original_sequence_number); | 571 pending_retransmissions_.find(original_sequence_number); |
562 if (it != pending_retransmissions_.end()) { | 572 if (it != pending_retransmissions_.end()) { |
563 pending_retransmissions_.erase(it); | 573 pending_retransmissions_.erase(it); |
564 } else { | 574 } else { |
565 DLOG(DFATAL) << "Expected sequence number to be in " | 575 DLOG(DFATAL) << "Expected sequence number to be in " |
566 << "pending_retransmissions_. sequence_number: " | 576 << "pending_retransmissions_. sequence_number: " |
567 << original_sequence_number; | 577 << original_sequence_number; |
568 } | 578 } |
569 // A notifier may be waiting to hear about ACKs for the original sequence | 579 // Inform the ack notifier of retransmissions so it can calculate the |
570 // number. Inform them that the sequence number has changed. | 580 // retransmit rate. |
571 ack_notifier_manager_.UpdateSequenceNumber(original_sequence_number, | 581 ack_notifier_manager_.OnPacketRetransmitted(original_sequence_number, |
572 sequence_number); | 582 sequence_number, bytes); |
573 } | 583 } |
574 | 584 |
575 if (pending_timer_transmission_count_ > 0) { | 585 if (pending_timer_transmission_count_ > 0) { |
576 --pending_timer_transmission_count_; | 586 --pending_timer_transmission_count_; |
577 } | 587 } |
578 | 588 |
579 if (unacked_packets_.bytes_in_flight() == 0) { | 589 if (unacked_packets_.bytes_in_flight() == 0) { |
580 // TODO(ianswett): Consider being less aggressive to force a new | 590 // TODO(ianswett): Consider being less aggressive to force a new |
581 // recent_min_rtt, likely by not discarding a relatively new sample. | 591 // recent_min_rtt, likely by not discarding a relatively new sample. |
582 DVLOG(1) << "Sampling a new recent min rtt within 2 samples. currently:" | 592 DVLOG(1) << "Sampling a new recent min rtt within 2 samples. currently:" |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 // Set up a pacing sender with a 1 millisecond alarm granularity, the same as | 1010 // Set up a pacing sender with a 1 millisecond alarm granularity, the same as |
1001 // the default granularity of the Linux kernel's FQ qdisc. | 1011 // the default granularity of the Linux kernel's FQ qdisc. |
1002 using_pacing_ = true; | 1012 using_pacing_ = true; |
1003 send_algorithm_.reset( | 1013 send_algorithm_.reset( |
1004 new PacingSender(send_algorithm_.release(), | 1014 new PacingSender(send_algorithm_.release(), |
1005 QuicTime::Delta::FromMilliseconds(1), | 1015 QuicTime::Delta::FromMilliseconds(1), |
1006 kInitialUnpacedBurst)); | 1016 kInitialUnpacedBurst)); |
1007 } | 1017 } |
1008 | 1018 |
1009 } // namespace net | 1019 } // namespace net |
OLD | NEW |