| 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/core/quic_sent_packet_manager.h" | 5 #include "net/quic/core/quic_sent_packet_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 const size_t kMinTimeoutsBeforePathDegrading = 2; | 35 const size_t kMinTimeoutsBeforePathDegrading = 2; |
| 36 | 36 |
| 37 // Ensure the handshake timer isnt't faster than 10ms. | 37 // Ensure the handshake timer isnt't faster than 10ms. |
| 38 // This limits the tenth retransmitted packet to 10s after the initial CHLO. | 38 // This limits the tenth retransmitted packet to 10s after the initial CHLO. |
| 39 static const int64_t kMinHandshakeTimeoutMs = 10; | 39 static const int64_t kMinHandshakeTimeoutMs = 10; |
| 40 | 40 |
| 41 // Sends up to two tail loss probes before firing an RTO, | 41 // Sends up to two tail loss probes before firing an RTO, |
| 42 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. | 42 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. |
| 43 static const size_t kDefaultMaxTailLossProbes = 2; | 43 static const size_t kDefaultMaxTailLossProbes = 2; |
| 44 | 44 |
| 45 // Number of unpaced packets to send after quiescence. |
| 46 static const size_t kInitialUnpacedBurst = 10; |
| 47 |
| 45 bool HasCryptoHandshake(const TransmissionInfo& transmission_info) { | 48 bool HasCryptoHandshake(const TransmissionInfo& transmission_info) { |
| 46 DCHECK(!transmission_info.has_crypto_handshake || | 49 DCHECK(!transmission_info.has_crypto_handshake || |
| 47 !transmission_info.retransmittable_frames.empty()); | 50 !transmission_info.retransmittable_frames.empty()); |
| 48 return transmission_info.has_crypto_handshake; | 51 return transmission_info.has_crypto_handshake; |
| 49 } | 52 } |
| 50 | 53 |
| 51 } // namespace | 54 } // namespace |
| 52 | 55 |
| 53 #define ENDPOINT \ | 56 #define ENDPOINT \ |
| 54 (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ") | 57 (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ") |
| (...skipping 27 matching lines...) Expand all Loading... |
| 82 receive_buffer_bytes_(kDefaultSocketReceiveBuffer), | 85 receive_buffer_bytes_(kDefaultSocketReceiveBuffer), |
| 83 least_packet_awaited_by_peer_(1), | 86 least_packet_awaited_by_peer_(1), |
| 84 first_rto_transmission_(0), | 87 first_rto_transmission_(0), |
| 85 consecutive_rto_count_(0), | 88 consecutive_rto_count_(0), |
| 86 consecutive_tlp_count_(0), | 89 consecutive_tlp_count_(0), |
| 87 consecutive_crypto_retransmission_count_(0), | 90 consecutive_crypto_retransmission_count_(0), |
| 88 pending_timer_transmission_count_(0), | 91 pending_timer_transmission_count_(0), |
| 89 max_tail_loss_probes_(kDefaultMaxTailLossProbes), | 92 max_tail_loss_probes_(kDefaultMaxTailLossProbes), |
| 90 enable_half_rtt_tail_loss_probe_(false), | 93 enable_half_rtt_tail_loss_probe_(false), |
| 91 using_pacing_(false), | 94 using_pacing_(false), |
| 92 using_inline_pacing_(false), | |
| 93 use_new_rto_(false), | 95 use_new_rto_(false), |
| 94 undo_pending_retransmits_(false), | 96 undo_pending_retransmits_(false), |
| 95 largest_newly_acked_(0), | 97 largest_newly_acked_(0), |
| 96 largest_mtu_acked_(0), | 98 largest_mtu_acked_(0), |
| 97 handshake_confirmed_(false) {} | 99 handshake_confirmed_(false) {} |
| 98 | 100 |
| 99 QuicSentPacketManager::~QuicSentPacketManager() {} | 101 QuicSentPacketManager::~QuicSentPacketManager() {} |
| 100 | 102 |
| 101 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { | 103 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { |
| 102 if (config.HasReceivedInitialRoundTripTimeUs() && | 104 if (config.HasReceivedInitialRoundTripTimeUs() && |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 | 188 |
| 187 void QuicSentPacketManager::SetNumOpenStreams(size_t num_streams) { | 189 void QuicSentPacketManager::SetNumOpenStreams(size_t num_streams) { |
| 188 if (n_connection_simulation_) { | 190 if (n_connection_simulation_) { |
| 189 // Ensure the number of connections is between 1 and 5. | 191 // Ensure the number of connections is between 1 and 5. |
| 190 send_algorithm_->SetNumEmulatedConnections( | 192 send_algorithm_->SetNumEmulatedConnections( |
| 191 min<size_t>(5, max<size_t>(1, num_streams))); | 193 min<size_t>(5, max<size_t>(1, num_streams))); |
| 192 } | 194 } |
| 193 } | 195 } |
| 194 | 196 |
| 195 void QuicSentPacketManager::SetMaxPacingRate(QuicBandwidth max_pacing_rate) { | 197 void QuicSentPacketManager::SetMaxPacingRate(QuicBandwidth max_pacing_rate) { |
| 196 if (using_inline_pacing_) { | 198 if (using_pacing_) { |
| 197 pacing_sender_.SetMaxPacingRate(max_pacing_rate); | |
| 198 } else if (using_pacing_) { | |
| 199 static_cast<PacingSender*>(send_algorithm_.get()) | 199 static_cast<PacingSender*>(send_algorithm_.get()) |
| 200 ->SetMaxPacingRate(max_pacing_rate); | 200 ->SetMaxPacingRate(max_pacing_rate); |
| 201 } | 201 } |
| 202 } | 202 } |
| 203 | 203 |
| 204 void QuicSentPacketManager::SetHandshakeConfirmed() { | 204 void QuicSentPacketManager::SetHandshakeConfirmed() { |
| 205 handshake_confirmed_ = true; | 205 handshake_confirmed_ = true; |
| 206 } | 206 } |
| 207 | 207 |
| 208 void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame, | 208 void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 least_packet_awaited_by_peer_ = ack_frame.packets.Min(); | 276 least_packet_awaited_by_peer_ = ack_frame.packets.Min(); |
| 277 } | 277 } |
| 278 } | 278 } |
| 279 | 279 |
| 280 void QuicSentPacketManager::MaybeInvokeCongestionEvent( | 280 void QuicSentPacketManager::MaybeInvokeCongestionEvent( |
| 281 bool rtt_updated, | 281 bool rtt_updated, |
| 282 QuicByteCount bytes_in_flight) { | 282 QuicByteCount bytes_in_flight) { |
| 283 if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) { | 283 if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) { |
| 284 return; | 284 return; |
| 285 } | 285 } |
| 286 if (using_inline_pacing_) { | 286 send_algorithm_->OnCongestionEvent(rtt_updated, bytes_in_flight, |
| 287 pacing_sender_.OnCongestionEvent(rtt_updated, bytes_in_flight, | |
| 288 packets_acked_, packets_lost_); | 287 packets_acked_, packets_lost_); |
| 289 } else { | |
| 290 send_algorithm_->OnCongestionEvent(rtt_updated, bytes_in_flight, | |
| 291 packets_acked_, packets_lost_); | |
| 292 } | |
| 293 packets_acked_.clear(); | 288 packets_acked_.clear(); |
| 294 packets_lost_.clear(); | 289 packets_lost_.clear(); |
| 295 if (network_change_visitor_ != nullptr) { | 290 if (network_change_visitor_ != nullptr) { |
| 296 network_change_visitor_->OnCongestionChange(); | 291 network_change_visitor_->OnCongestionChange(); |
| 297 } | 292 } |
| 298 } | 293 } |
| 299 | 294 |
| 300 void QuicSentPacketManager::HandleAckForSentPackets( | 295 void QuicSentPacketManager::HandleAckForSentPackets( |
| 301 const QuicAckFrame& ack_frame) { | 296 const QuicAckFrame& ack_frame) { |
| 302 // Go through the packets we have not received an ack for and see if this | 297 // Go through the packets we have not received an ack for and see if this |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 << "Cannot send empty packets."; | 553 << "Cannot send empty packets."; |
| 559 | 554 |
| 560 if (delegate_ == nullptr && original_packet_number != 0) { | 555 if (delegate_ == nullptr && original_packet_number != 0) { |
| 561 pending_retransmissions_.erase(original_packet_number); | 556 pending_retransmissions_.erase(original_packet_number); |
| 562 } | 557 } |
| 563 | 558 |
| 564 if (pending_timer_transmission_count_ > 0) { | 559 if (pending_timer_transmission_count_ > 0) { |
| 565 --pending_timer_transmission_count_; | 560 --pending_timer_transmission_count_; |
| 566 } | 561 } |
| 567 | 562 |
| 568 bool in_flight; | 563 // TODO(ianswett): Remove sent_time, because it's unused. |
| 569 if (using_inline_pacing_) { | 564 const bool in_flight = send_algorithm_->OnPacketSent( |
| 570 in_flight = pacing_sender_.OnPacketSent( | 565 sent_time, unacked_packets_.bytes_in_flight(), packet_number, |
| 571 sent_time, unacked_packets_.bytes_in_flight(), packet_number, | 566 serialized_packet->encrypted_length, has_retransmittable_data); |
| 572 serialized_packet->encrypted_length, has_retransmittable_data); | |
| 573 } else { | |
| 574 in_flight = send_algorithm_->OnPacketSent( | |
| 575 sent_time, unacked_packets_.bytes_in_flight(), packet_number, | |
| 576 serialized_packet->encrypted_length, has_retransmittable_data); | |
| 577 } | |
| 578 | 567 |
| 579 unacked_packets_.AddSentPacket(serialized_packet, original_packet_number, | 568 unacked_packets_.AddSentPacket(serialized_packet, original_packet_number, |
| 580 transmission_type, sent_time, in_flight); | 569 transmission_type, sent_time, in_flight); |
| 581 // Reset the retransmission timer anytime a pending packet is sent. | 570 // Reset the retransmission timer anytime a pending packet is sent. |
| 582 return in_flight; | 571 return in_flight; |
| 583 } | 572 } |
| 584 | 573 |
| 585 void QuicSentPacketManager::OnRetransmissionTimeout() { | 574 void QuicSentPacketManager::OnRetransmissionTimeout() { |
| 586 DCHECK(unacked_packets_.HasInFlightPackets()); | 575 DCHECK(unacked_packets_.HasInFlightPackets()); |
| 587 DCHECK_EQ(0u, pending_timer_transmission_count_); | 576 DCHECK_EQ(0u, pending_timer_transmission_count_); |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 } | 768 } |
| 780 | 769 |
| 781 QuicTime::Delta QuicSentPacketManager::TimeUntilSend(QuicTime now, | 770 QuicTime::Delta QuicSentPacketManager::TimeUntilSend(QuicTime now, |
| 782 QuicPathId* path_id) { | 771 QuicPathId* path_id) { |
| 783 QuicTime::Delta delay = QuicTime::Delta::Infinite(); | 772 QuicTime::Delta delay = QuicTime::Delta::Infinite(); |
| 784 // The TLP logic is entirely contained within QuicSentPacketManager, so the | 773 // The TLP logic is entirely contained within QuicSentPacketManager, so the |
| 785 // send algorithm does not need to be consulted. | 774 // send algorithm does not need to be consulted. |
| 786 if (pending_timer_transmission_count_ > 0) { | 775 if (pending_timer_transmission_count_ > 0) { |
| 787 delay = QuicTime::Delta::Zero(); | 776 delay = QuicTime::Delta::Zero(); |
| 788 } else { | 777 } else { |
| 789 if (using_inline_pacing_) { | 778 delay = |
| 790 delay = | 779 send_algorithm_->TimeUntilSend(now, unacked_packets_.bytes_in_flight()); |
| 791 pacing_sender_.TimeUntilSend(now, unacked_packets_.bytes_in_flight()); | |
| 792 } else { | |
| 793 delay = send_algorithm_->TimeUntilSend( | |
| 794 now, unacked_packets_.bytes_in_flight()); | |
| 795 } | |
| 796 } | 780 } |
| 797 if (!delay.IsInfinite()) { | 781 if (!delay.IsInfinite()) { |
| 798 *path_id = path_id_; | 782 *path_id = path_id_; |
| 799 } | 783 } |
| 800 return delay; | 784 return delay; |
| 801 } | 785 } |
| 802 | 786 |
| 803 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { | 787 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { |
| 804 // Don't set the timer if there are no packets in flight or we've already | 788 // Don't set the timer if there are no packets in flight or we've already |
| 805 // queued a tlp transmission and it hasn't been sent yet. | 789 // queued a tlp transmission and it hasn't been sent yet. |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 936 while (it != pending_retransmissions_.end()) { | 920 while (it != pending_retransmissions_.end()) { |
| 937 if (unacked_packets_.HasRetransmittableFrames(it->first)) { | 921 if (unacked_packets_.HasRetransmittableFrames(it->first)) { |
| 938 ++it; | 922 ++it; |
| 939 continue; | 923 continue; |
| 940 } | 924 } |
| 941 it = pending_retransmissions_.erase(it); | 925 it = pending_retransmissions_.erase(it); |
| 942 } | 926 } |
| 943 } | 927 } |
| 944 | 928 |
| 945 void QuicSentPacketManager::EnablePacing() { | 929 void QuicSentPacketManager::EnablePacing() { |
| 946 if (FLAGS_quic_use_inline_pacing) { | 930 // TODO(ianswett): Replace with a method which wraps the send algorithm in a |
| 947 using_inline_pacing_ = true; | 931 // pacer every time a new algorithm is set. |
| 948 pacing_sender_.SetSender(send_algorithm_.get(), false); | 932 if (using_pacing_) { |
| 949 } else { | 933 return; |
| 950 // TODO(ianswett): Replace with a method which wraps the send algorithm in a | 934 } |
| 951 // pacer every time a new algorithm is set. | |
| 952 if (using_pacing_) { | |
| 953 return; | |
| 954 } | |
| 955 | 935 |
| 956 // Set up a pacing sender with a 1 millisecond alarm granularity, the same | 936 // Set up a pacing sender with a 1 millisecond alarm granularity, the same as |
| 957 // as the default granularity of the Linux kernel's FQ qdisc. | 937 // the default granularity of the Linux kernel's FQ qdisc. |
| 958 using_pacing_ = true; | 938 using_pacing_ = true; |
| 959 PacingSender* pacing_sender = new PacingSender; | 939 send_algorithm_.reset(new PacingSender(send_algorithm_.release(), |
| 960 pacing_sender->SetSender(send_algorithm_.release(), true); | 940 QuicTime::Delta::FromMilliseconds(1), |
| 961 send_algorithm_.reset(pacing_sender); | 941 kInitialUnpacedBurst)); |
| 962 } | |
| 963 } | 942 } |
| 964 | 943 |
| 965 void QuicSentPacketManager::OnConnectionMigration(QuicPathId, | 944 void QuicSentPacketManager::OnConnectionMigration(QuicPathId, |
| 966 PeerAddressChangeType type) { | 945 PeerAddressChangeType type) { |
| 967 if (type == PORT_CHANGE || type == IPV4_SUBNET_CHANGE) { | 946 if (type == PORT_CHANGE || type == IPV4_SUBNET_CHANGE) { |
| 968 // Rtt and cwnd do not need to be reset when the peer address change is | 947 // Rtt and cwnd do not need to be reset when the peer address change is |
| 969 // considered to be caused by NATs. | 948 // considered to be caused by NATs. |
| 970 return; | 949 return; |
| 971 } | 950 } |
| 972 consecutive_rto_count_ = 0; | 951 consecutive_rto_count_ = 0; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 TransmissionInfo* QuicSentPacketManager::GetMutableTransmissionInfo( | 998 TransmissionInfo* QuicSentPacketManager::GetMutableTransmissionInfo( |
| 1020 QuicPacketNumber packet_number) { | 999 QuicPacketNumber packet_number) { |
| 1021 return unacked_packets_.GetMutableTransmissionInfo(packet_number); | 1000 return unacked_packets_.GetMutableTransmissionInfo(packet_number); |
| 1022 } | 1001 } |
| 1023 | 1002 |
| 1024 void QuicSentPacketManager::RemoveObsoletePackets() { | 1003 void QuicSentPacketManager::RemoveObsoletePackets() { |
| 1025 unacked_packets_.RemoveObsoletePackets(); | 1004 unacked_packets_.RemoveObsoletePackets(); |
| 1026 } | 1005 } |
| 1027 | 1006 |
| 1028 } // namespace net | 1007 } // namespace net |
| OLD | NEW |