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 "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "net/quic/congestion_control/pacing_sender.h" | 9 #include "net/quic/congestion_control/pacing_sender.h" |
10 #include "net/quic/quic_ack_notifier_manager.h" | 10 #include "net/quic/quic_ack_notifier_manager.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 } | 97 } |
98 | 98 |
99 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { | 99 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { |
100 if (config.initial_round_trip_time_us() > 0 && | 100 if (config.initial_round_trip_time_us() > 0 && |
101 rtt_sample_.IsInfinite()) { | 101 rtt_sample_.IsInfinite()) { |
102 // The initial rtt should already be set on the client side. | 102 // The initial rtt should already be set on the client side. |
103 DVLOG_IF(1, !is_server_) | 103 DVLOG_IF(1, !is_server_) |
104 << "Client did not set an initial RTT, but did negotiate one."; | 104 << "Client did not set an initial RTT, but did negotiate one."; |
105 rtt_sample_ = | 105 rtt_sample_ = |
106 QuicTime::Delta::FromMicroseconds(config.initial_round_trip_time_us()); | 106 QuicTime::Delta::FromMicroseconds(config.initial_round_trip_time_us()); |
| 107 send_algorithm_->UpdateRtt(rtt_sample_); |
107 } | 108 } |
108 if (config.congestion_control() == kPACE) { | 109 if (config.congestion_control() == kPACE) { |
109 MaybeEnablePacing(); | 110 MaybeEnablePacing(); |
110 } | 111 } |
111 send_algorithm_->SetFromConfig(config, is_server_); | 112 send_algorithm_->SetFromConfig(config, is_server_); |
112 } | 113 } |
113 | 114 |
114 void QuicSentPacketManager::SetMaxPacketSize(QuicByteCount max_packet_size) { | 115 void QuicSentPacketManager::SetMaxPacketSize(QuicByteCount max_packet_size) { |
115 send_algorithm_->SetMaxPacketSize(max_packet_size); | 116 send_algorithm_->SetMaxPacketSize(max_packet_size); |
116 } | 117 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 } | 175 } |
175 previous_transmissions->insert(new_sequence_number); | 176 previous_transmissions->insert(new_sequence_number); |
176 unacked_packets_[new_sequence_number].previous_transmissions = | 177 unacked_packets_[new_sequence_number].previous_transmissions = |
177 previous_transmissions; | 178 previous_transmissions; |
178 | 179 |
179 DCHECK(HasRetransmittableFrames(new_sequence_number)); | 180 DCHECK(HasRetransmittableFrames(new_sequence_number)); |
180 } | 181 } |
181 | 182 |
182 bool QuicSentPacketManager::OnIncomingAck( | 183 bool QuicSentPacketManager::OnIncomingAck( |
183 const ReceivedPacketInfo& received_info, QuicTime ack_receive_time) { | 184 const ReceivedPacketInfo& received_info, QuicTime ack_receive_time) { |
184 // Determine if the least unacked sequence number is being acked. | 185 // We rely on delta_time_largest_observed to compute an RTT estimate, so |
185 QuicPacketSequenceNumber least_unacked_sent_before = | 186 // we only update rtt when the largest observed gets acked. |
186 GetLeastUnackedSentPacket(); | 187 bool largest_observed_acked = |
187 // TODO(ianswett): Consider a non-TCP metric for determining the connection | 188 ContainsKey(unacked_packets_, received_info.largest_observed); |
188 // is making progress, since QUIC has out of order delivery. | |
189 bool new_least_unacked = !IsAwaitingPacket(received_info, | |
190 least_unacked_sent_before); | |
191 | |
192 MaybeUpdateRTT(received_info, ack_receive_time); | 189 MaybeUpdateRTT(received_info, ack_receive_time); |
193 HandleAckForSentPackets(received_info); | 190 HandleAckForSentPackets(received_info); |
194 MaybeRetransmitOnAckFrame(received_info, ack_receive_time); | 191 MaybeRetransmitOnAckFrame(received_info, ack_receive_time); |
195 | 192 |
196 if (new_least_unacked) { | 193 // Anytime we are making forward progress and have a new RTT estimate, reset |
| 194 // the backoff counters. |
| 195 if (largest_observed_acked) { |
197 // Reset all retransmit counters any time a new packet is acked. | 196 // Reset all retransmit counters any time a new packet is acked. |
198 consecutive_rto_count_ = 0; | 197 consecutive_rto_count_ = 0; |
199 consecutive_tlp_count_ = 0; | 198 consecutive_tlp_count_ = 0; |
200 consecutive_crypto_retransmission_count_ = 0; | 199 consecutive_crypto_retransmission_count_ = 0; |
201 } | 200 } |
202 | 201 |
203 // Always reset the retransmission alarm when an ack comes in, since we now | 202 // Always reset the retransmission alarm when an ack comes in, since we now |
204 // have a better estimate of the current rtt than when it was set. | 203 // have a better estimate of the current rtt than when it was set. |
205 return true; | 204 return true; |
206 } | 205 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 void QuicSentPacketManager::RetransmitUnackedPackets( | 296 void QuicSentPacketManager::RetransmitUnackedPackets( |
298 RetransmissionType retransmission_type) { | 297 RetransmissionType retransmission_type) { |
299 if (unacked_packets_.empty()) { | 298 if (unacked_packets_.empty()) { |
300 return; | 299 return; |
301 } | 300 } |
302 | 301 |
303 for (UnackedPacketMap::iterator unacked_it = unacked_packets_.begin(); | 302 for (UnackedPacketMap::iterator unacked_it = unacked_packets_.begin(); |
304 unacked_it != unacked_packets_.end(); ++unacked_it) { | 303 unacked_it != unacked_packets_.end(); ++unacked_it) { |
305 const RetransmittableFrames* frames = | 304 const RetransmittableFrames* frames = |
306 unacked_it->second.retransmittable_frames; | 305 unacked_it->second.retransmittable_frames; |
307 if (frames == NULL) { | |
308 continue; | |
309 } | |
310 if (retransmission_type == ALL_PACKETS || | 306 if (retransmission_type == ALL_PACKETS || |
311 frames->encryption_level() == ENCRYPTION_INITIAL) { | 307 (frames != NULL && frames->encryption_level() == ENCRYPTION_INITIAL)) { |
312 // TODO(satyamshekhar): Think about congestion control here. | 308 if (frames) { |
313 // Specifically, about the retransmission count of packets being sent | |
314 // proactively to achieve 0 (minimal) RTT. | |
315 if (unacked_it->second.retransmittable_frames) { | |
316 OnPacketAbandoned(unacked_it); | 309 OnPacketAbandoned(unacked_it); |
317 MarkForRetransmission(unacked_it->first, NACK_RETRANSMISSION); | 310 MarkForRetransmission(unacked_it->first, NACK_RETRANSMISSION); |
318 } else { | 311 } else { |
319 DiscardUnackedPacket(unacked_it->first); | 312 DiscardUnackedPacket(unacked_it->first); |
320 } | 313 } |
321 } | 314 } |
322 } | 315 } |
323 } | 316 } |
324 | 317 |
325 void QuicSentPacketManager::MarkForRetransmission( | 318 void QuicSentPacketManager::MarkForRetransmission( |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 QuicSentPacketManager::UnackedPacketMap::iterator | 384 QuicSentPacketManager::UnackedPacketMap::iterator |
392 QuicSentPacketManager::MarkPacketHandled( | 385 QuicSentPacketManager::MarkPacketHandled( |
393 QuicPacketSequenceNumber sequence_number, ReceivedByPeer received_by_peer) { | 386 QuicPacketSequenceNumber sequence_number, ReceivedByPeer received_by_peer) { |
394 DCHECK(ContainsKey(unacked_packets_, sequence_number)); | 387 DCHECK(ContainsKey(unacked_packets_, sequence_number)); |
395 | 388 |
396 // If this packet is pending, remove it and inform the send algorithm. | 389 // If this packet is pending, remove it and inform the send algorithm. |
397 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); | 390 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); |
398 if (it->second.pending) { | 391 if (it->second.pending) { |
399 size_t bytes_sent = packet_history_map_[sequence_number]->bytes_sent(); | 392 size_t bytes_sent = packet_history_map_[sequence_number]->bytes_sent(); |
400 if (received_by_peer == RECEIVED_BY_PEER) { | 393 if (received_by_peer == RECEIVED_BY_PEER) { |
401 send_algorithm_->OnPacketAcked(sequence_number, bytes_sent, rtt_sample_); | 394 send_algorithm_->OnPacketAcked(sequence_number, bytes_sent); |
402 } else { | 395 } else { |
403 // It's been abandoned. | 396 // It's been abandoned. |
404 send_algorithm_->OnPacketAbandoned(sequence_number, bytes_sent); | 397 send_algorithm_->OnPacketAbandoned(sequence_number, bytes_sent); |
405 } | 398 } |
406 it->second.pending = false; | 399 it->second.pending = false; |
407 } | 400 } |
408 | 401 |
409 // If this packet has never been retransmitted, then simply drop it. | 402 // If this packet has never been retransmitted, then simply drop it. |
410 if (it->second.previous_transmissions == NULL) { | 403 if (it->second.previous_transmissions == NULL) { |
411 ++it; | 404 ++it; |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 return unacked_packets; | 536 return unacked_packets; |
544 } | 537 } |
545 | 538 |
546 bool QuicSentPacketManager::OnPacketSent( | 539 bool QuicSentPacketManager::OnPacketSent( |
547 QuicPacketSequenceNumber sequence_number, | 540 QuicPacketSequenceNumber sequence_number, |
548 QuicTime sent_time, | 541 QuicTime sent_time, |
549 QuicByteCount bytes, | 542 QuicByteCount bytes, |
550 TransmissionType transmission_type, | 543 TransmissionType transmission_type, |
551 HasRetransmittableData has_retransmittable_data) { | 544 HasRetransmittableData has_retransmittable_data) { |
552 DCHECK_LT(0u, sequence_number); | 545 DCHECK_LT(0u, sequence_number); |
553 // In some edge cases, on some platforms (such as Windows), it is possible | 546 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); |
554 // that we were write-blocked when we tried to send a packet, and then decided | 547 // In rare circumstances, the packet could be serialized, sent, and then acked |
555 // not to send the packet (such as when the encryption key changes, and we | 548 // before OnPacketSent is called. |
556 // "discard" the unsent packet). In that rare case, we may indeed | 549 if (it == unacked_packets_.end()) { |
557 // asynchronously (later) send the packet, calling this method, but the | |
558 // sequence number may already be erased from unacked_packets_ map. In that | |
559 // case, we can just return false since the packet will not be tracked for | |
560 // retransmission. | |
561 if (!ContainsKey(unacked_packets_, sequence_number)) | |
562 return false; | 550 return false; |
563 DCHECK(!unacked_packets_[sequence_number].pending); | 551 } |
564 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); | 552 DCHECK(!it->second.pending); |
565 | 553 |
566 // Only track packets the send algorithm wants us to track. | 554 // Only track packets the send algorithm wants us to track. |
567 if (!send_algorithm_->OnPacketSent(sent_time, sequence_number, bytes, | 555 if (!send_algorithm_->OnPacketSent(sent_time, sequence_number, bytes, |
568 transmission_type, | 556 transmission_type, |
569 has_retransmittable_data)) { | 557 has_retransmittable_data)) { |
570 DCHECK(it->second.retransmittable_frames == NULL); | 558 DCHECK(it->second.retransmittable_frames == NULL); |
571 unacked_packets_.erase(it); | 559 unacked_packets_.erase(it); |
572 // Do not reset the retransmission timer, since the packet isn't tracked. | 560 // Do not reset the retransmission timer, since the packet isn't tracked. |
573 return false; | 561 return false; |
574 } | 562 } |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 // sequence numbers will include the ACK aggregation delay. | 786 // sequence numbers will include the ACK aggregation delay. |
799 UnackedPacketMap::iterator unacked_it = | 787 UnackedPacketMap::iterator unacked_it = |
800 unacked_packets_.find(received_info.largest_observed); | 788 unacked_packets_.find(received_info.largest_observed); |
801 if (unacked_it == unacked_packets_.end()) { | 789 if (unacked_it == unacked_packets_.end()) { |
802 return; | 790 return; |
803 } | 791 } |
804 const TransmissionInfo* transmission_info = &unacked_it->second; | 792 const TransmissionInfo* transmission_info = &unacked_it->second; |
805 if (transmission_info == NULL) { | 793 if (transmission_info == NULL) { |
806 return; | 794 return; |
807 } | 795 } |
| 796 // Don't update the RTT if it hasn't been sent. |
| 797 if (transmission_info->sent_time == QuicTime::Zero()) { |
| 798 return; |
| 799 } |
808 | 800 |
809 QuicTime::Delta send_delta = | 801 QuicTime::Delta send_delta = |
810 ack_receive_time.Subtract(transmission_info->sent_time); | 802 ack_receive_time.Subtract(transmission_info->sent_time); |
811 if (send_delta > received_info.delta_time_largest_observed) { | 803 if (send_delta > received_info.delta_time_largest_observed) { |
812 rtt_sample_ = send_delta.Subtract( | 804 rtt_sample_ = send_delta.Subtract( |
813 received_info.delta_time_largest_observed); | 805 received_info.delta_time_largest_observed); |
814 } else if (rtt_sample_.IsInfinite()) { | 806 } else if (rtt_sample_.IsInfinite()) { |
815 // Even though we received information from the peer suggesting | 807 // Even though we received information from the peer suggesting |
816 // an invalid (negative) RTT, we can use the send delta as an | 808 // an invalid (negative) RTT, we can use the send delta as an |
817 // approximation until we get a better estimate. | 809 // approximation until we get a better estimate. |
818 rtt_sample_ = send_delta; | 810 rtt_sample_ = send_delta; |
819 } | 811 } |
| 812 send_algorithm_->UpdateRtt(rtt_sample_); |
820 } | 813 } |
821 | 814 |
822 QuicTime::Delta QuicSentPacketManager::TimeUntilSend( | 815 QuicTime::Delta QuicSentPacketManager::TimeUntilSend( |
823 QuicTime now, | 816 QuicTime now, |
824 TransmissionType transmission_type, | 817 TransmissionType transmission_type, |
825 HasRetransmittableData retransmittable, | 818 HasRetransmittableData retransmittable, |
826 IsHandshake handshake) { | 819 IsHandshake handshake) { |
827 return send_algorithm_->TimeUntilSend(now, transmission_type, retransmittable, | 820 return send_algorithm_->TimeUntilSend(now, transmission_type, retransmittable, |
828 handshake); | 821 handshake); |
829 } | 822 } |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 } | 990 } |
998 previous_transmissions->erase(sequence_number); | 991 previous_transmissions->erase(sequence_number); |
999 if (previous_transmissions->size() == 1) { | 992 if (previous_transmissions->size() == 1) { |
1000 QuicPacketSequenceNumber current = *previous_transmissions->begin(); | 993 QuicPacketSequenceNumber current = *previous_transmissions->begin(); |
1001 unacked_packets_[current].previous_transmissions = NULL; | 994 unacked_packets_[current].previous_transmissions = NULL; |
1002 delete previous_transmissions; | 995 delete previous_transmissions; |
1003 } | 996 } |
1004 } | 997 } |
1005 | 998 |
1006 } // namespace net | 999 } // namespace net |
OLD | NEW |