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