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 | |
48 bool HasCryptoHandshake(const TransmissionInfo& transmission_info) { | 45 bool HasCryptoHandshake(const TransmissionInfo& transmission_info) { |
49 DCHECK(!transmission_info.has_crypto_handshake || | 46 DCHECK(!transmission_info.has_crypto_handshake || |
50 !transmission_info.retransmittable_frames.empty()); | 47 !transmission_info.retransmittable_frames.empty()); |
51 return transmission_info.has_crypto_handshake; | 48 return transmission_info.has_crypto_handshake; |
52 } | 49 } |
53 | 50 |
54 } // namespace | 51 } // namespace |
55 | 52 |
56 #define ENDPOINT \ | 53 #define ENDPOINT \ |
57 (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ") | 54 (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ") |
58 | 55 |
59 QuicSentPacketManager::QuicSentPacketManager( | 56 QuicSentPacketManager::QuicSentPacketManager( |
60 Perspective perspective, | 57 Perspective perspective, |
61 QuicPathId path_id, | 58 QuicPathId path_id, |
62 const QuicClock* clock, | 59 const QuicClock* clock, |
63 QuicConnectionStats* stats, | 60 QuicConnectionStats* stats, |
64 CongestionControlType congestion_control_type, | 61 CongestionControlType congestion_control_type, |
65 LossDetectionType loss_type, | 62 LossDetectionType loss_type, |
66 MultipathDelegateInterface* delegate) | 63 MultipathDelegateInterface* delegate) |
67 : unacked_packets_(), | 64 : unacked_packets_(), |
68 perspective_(perspective), | 65 perspective_(perspective), |
69 path_id_(path_id), | 66 path_id_(path_id), |
70 clock_(clock), | 67 clock_(clock), |
71 stats_(stats), | 68 stats_(stats), |
72 delegate_(delegate), | 69 delegate_(delegate), |
73 debug_delegate_(nullptr), | 70 debug_delegate_(nullptr), |
74 network_change_visitor_(nullptr), | 71 network_change_visitor_(nullptr), |
75 initial_congestion_window_(kInitialCongestionWindow), | 72 initial_congestion_window_(kInitialCongestionWindow), |
76 send_algorithm_( | |
77 SendAlgorithmInterface::Create(clock, | |
78 &rtt_stats_, | |
79 congestion_control_type, | |
80 stats, | |
81 initial_congestion_window_)), | |
82 loss_algorithm_(&general_loss_algorithm_), | 73 loss_algorithm_(&general_loss_algorithm_), |
83 general_loss_algorithm_(loss_type), | 74 general_loss_algorithm_(loss_type), |
84 n_connection_simulation_(false), | 75 n_connection_simulation_(false), |
85 receive_buffer_bytes_(kDefaultSocketReceiveBuffer), | 76 receive_buffer_bytes_(kDefaultSocketReceiveBuffer), |
86 least_packet_awaited_by_peer_(1), | 77 least_packet_awaited_by_peer_(1), |
87 first_rto_transmission_(0), | 78 first_rto_transmission_(0), |
88 consecutive_rto_count_(0), | 79 consecutive_rto_count_(0), |
89 consecutive_tlp_count_(0), | 80 consecutive_tlp_count_(0), |
90 consecutive_crypto_retransmission_count_(0), | 81 consecutive_crypto_retransmission_count_(0), |
91 pending_timer_transmission_count_(0), | 82 pending_timer_transmission_count_(0), |
92 max_tail_loss_probes_(kDefaultMaxTailLossProbes), | 83 max_tail_loss_probes_(kDefaultMaxTailLossProbes), |
93 enable_half_rtt_tail_loss_probe_(false), | 84 enable_half_rtt_tail_loss_probe_(false), |
94 using_pacing_(false), | 85 using_pacing_(false), |
95 use_new_rto_(false), | 86 use_new_rto_(false), |
96 undo_pending_retransmits_(false), | 87 undo_pending_retransmits_(false), |
97 largest_newly_acked_(0), | 88 largest_newly_acked_(0), |
98 largest_mtu_acked_(0), | 89 largest_mtu_acked_(0), |
99 handshake_confirmed_(false) {} | 90 handshake_confirmed_(false) { |
| 91 SetSendAlgorithm(congestion_control_type); |
| 92 } |
100 | 93 |
101 QuicSentPacketManager::~QuicSentPacketManager() {} | 94 QuicSentPacketManager::~QuicSentPacketManager() {} |
102 | 95 |
103 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { | 96 void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) { |
104 if (config.HasReceivedInitialRoundTripTimeUs() && | 97 if (config.HasReceivedInitialRoundTripTimeUs() && |
105 config.ReceivedInitialRoundTripTimeUs() > 0) { | 98 config.ReceivedInitialRoundTripTimeUs() > 0) { |
106 rtt_stats_.set_initial_rtt_us( | 99 rtt_stats_.set_initial_rtt_us( |
107 max(kMinInitialRoundTripTimeUs, | 100 max(kMinInitialRoundTripTimeUs, |
108 min(kMaxInitialRoundTripTimeUs, | 101 min(kMaxInitialRoundTripTimeUs, |
109 config.ReceivedInitialRoundTripTimeUs()))); | 102 config.ReceivedInitialRoundTripTimeUs()))); |
110 } else if (config.HasInitialRoundTripTimeUsToSend() && | 103 } else if (config.HasInitialRoundTripTimeUsToSend() && |
111 config.GetInitialRoundTripTimeUsToSend() > 0) { | 104 config.GetInitialRoundTripTimeUsToSend() > 0) { |
112 rtt_stats_.set_initial_rtt_us( | 105 rtt_stats_.set_initial_rtt_us( |
113 max(kMinInitialRoundTripTimeUs, | 106 max(kMinInitialRoundTripTimeUs, |
114 min(kMaxInitialRoundTripTimeUs, | 107 min(kMaxInitialRoundTripTimeUs, |
115 config.GetInitialRoundTripTimeUsToSend()))); | 108 config.GetInitialRoundTripTimeUsToSend()))); |
116 } | 109 } |
117 // TODO(ianswett): BBR is currently a server only feature. | 110 // TODO(ianswett): BBR is currently a server only feature. |
118 if (FLAGS_quic_allow_bbr && config.HasReceivedConnectionOptions() && | 111 if (FLAGS_quic_allow_bbr && config.HasReceivedConnectionOptions() && |
119 ContainsQuicTag(config.ReceivedConnectionOptions(), kTBBR)) { | 112 ContainsQuicTag(config.ReceivedConnectionOptions(), kTBBR)) { |
120 send_algorithm_.reset(SendAlgorithmInterface::Create( | 113 SetSendAlgorithm(kBBR); |
121 clock_, &rtt_stats_, kBBR, stats_, initial_congestion_window_)); | |
122 } | 114 } |
123 if (config.HasReceivedConnectionOptions() && | 115 if (config.HasReceivedConnectionOptions() && |
124 ContainsQuicTag(config.ReceivedConnectionOptions(), kRENO)) { | 116 ContainsQuicTag(config.ReceivedConnectionOptions(), kRENO)) { |
125 if (ContainsQuicTag(config.ReceivedConnectionOptions(), kBYTE)) { | 117 if (ContainsQuicTag(config.ReceivedConnectionOptions(), kBYTE)) { |
126 send_algorithm_.reset(SendAlgorithmInterface::Create( | 118 SetSendAlgorithm(kRenoBytes); |
127 clock_, &rtt_stats_, kRenoBytes, stats_, initial_congestion_window_)); | |
128 } else { | 119 } else { |
129 send_algorithm_.reset(SendAlgorithmInterface::Create( | 120 SetSendAlgorithm(kReno); |
130 clock_, &rtt_stats_, kReno, stats_, initial_congestion_window_)); | |
131 } | 121 } |
132 } else if (config.HasReceivedConnectionOptions() && | 122 } else if (config.HasReceivedConnectionOptions() && |
133 ContainsQuicTag(config.ReceivedConnectionOptions(), kBYTE)) { | 123 ContainsQuicTag(config.ReceivedConnectionOptions(), kBYTE)) { |
134 send_algorithm_.reset(SendAlgorithmInterface::Create( | 124 SetSendAlgorithm(kCubicBytes); |
135 clock_, &rtt_stats_, kCubicBytes, stats_, initial_congestion_window_)); | |
136 } | 125 } |
137 if (!FLAGS_quic_disable_pacing_for_perf_tests) { | 126 using_pacing_ = !FLAGS_quic_disable_pacing_for_perf_tests; |
138 EnablePacing(); | |
139 } | |
140 | 127 |
141 if (config.HasClientSentConnectionOption(k1CON, perspective_)) { | 128 if (config.HasClientSentConnectionOption(k1CON, perspective_)) { |
142 send_algorithm_->SetNumEmulatedConnections(1); | 129 send_algorithm_->SetNumEmulatedConnections(1); |
143 } | 130 } |
144 if (config.HasClientSentConnectionOption(kNCON, perspective_)) { | 131 if (config.HasClientSentConnectionOption(kNCON, perspective_)) { |
145 n_connection_simulation_ = true; | 132 n_connection_simulation_ = true; |
146 } | 133 } |
147 if (config.HasClientSentConnectionOption(kNTLP, perspective_)) { | 134 if (config.HasClientSentConnectionOption(kNTLP, perspective_)) { |
148 max_tail_loss_probes_ = 0; | 135 max_tail_loss_probes_ = 0; |
149 } | 136 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 | 175 |
189 void QuicSentPacketManager::SetNumOpenStreams(size_t num_streams) { | 176 void QuicSentPacketManager::SetNumOpenStreams(size_t num_streams) { |
190 if (n_connection_simulation_) { | 177 if (n_connection_simulation_) { |
191 // Ensure the number of connections is between 1 and 5. | 178 // Ensure the number of connections is between 1 and 5. |
192 send_algorithm_->SetNumEmulatedConnections( | 179 send_algorithm_->SetNumEmulatedConnections( |
193 min<size_t>(5, max<size_t>(1, num_streams))); | 180 min<size_t>(5, max<size_t>(1, num_streams))); |
194 } | 181 } |
195 } | 182 } |
196 | 183 |
197 void QuicSentPacketManager::SetMaxPacingRate(QuicBandwidth max_pacing_rate) { | 184 void QuicSentPacketManager::SetMaxPacingRate(QuicBandwidth max_pacing_rate) { |
198 if (using_pacing_) { | 185 pacing_sender_.set_max_pacing_rate(max_pacing_rate); |
199 static_cast<PacingSender*>(send_algorithm_.get()) | |
200 ->SetMaxPacingRate(max_pacing_rate); | |
201 } | |
202 } | 186 } |
203 | 187 |
204 void QuicSentPacketManager::SetHandshakeConfirmed() { | 188 void QuicSentPacketManager::SetHandshakeConfirmed() { |
205 handshake_confirmed_ = true; | 189 handshake_confirmed_ = true; |
206 } | 190 } |
207 | 191 |
208 void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame, | 192 void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame, |
209 QuicTime ack_receive_time) { | 193 QuicTime ack_receive_time) { |
210 DCHECK_LE(ack_frame.largest_observed, unacked_packets_.largest_sent_packet()); | 194 DCHECK_LE(ack_frame.largest_observed, unacked_packets_.largest_sent_packet()); |
211 QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight(); | 195 QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 least_packet_awaited_by_peer_ = ack_frame.packets.Min(); | 260 least_packet_awaited_by_peer_ = ack_frame.packets.Min(); |
277 } | 261 } |
278 } | 262 } |
279 | 263 |
280 void QuicSentPacketManager::MaybeInvokeCongestionEvent( | 264 void QuicSentPacketManager::MaybeInvokeCongestionEvent( |
281 bool rtt_updated, | 265 bool rtt_updated, |
282 QuicByteCount bytes_in_flight) { | 266 QuicByteCount bytes_in_flight) { |
283 if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) { | 267 if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) { |
284 return; | 268 return; |
285 } | 269 } |
286 send_algorithm_->OnCongestionEvent(rtt_updated, bytes_in_flight, | 270 if (using_pacing_) { |
| 271 pacing_sender_.OnCongestionEvent(rtt_updated, bytes_in_flight, |
287 packets_acked_, packets_lost_); | 272 packets_acked_, packets_lost_); |
| 273 } else { |
| 274 send_algorithm_->OnCongestionEvent(rtt_updated, bytes_in_flight, |
| 275 packets_acked_, packets_lost_); |
| 276 } |
288 packets_acked_.clear(); | 277 packets_acked_.clear(); |
289 packets_lost_.clear(); | 278 packets_lost_.clear(); |
290 if (network_change_visitor_ != nullptr) { | 279 if (network_change_visitor_ != nullptr) { |
291 network_change_visitor_->OnCongestionChange(); | 280 network_change_visitor_->OnCongestionChange(); |
292 } | 281 } |
293 } | 282 } |
294 | 283 |
295 void QuicSentPacketManager::HandleAckForSentPackets( | 284 void QuicSentPacketManager::HandleAckForSentPackets( |
296 const QuicAckFrame& ack_frame) { | 285 const QuicAckFrame& ack_frame) { |
297 // Go through the packets we have not received an ack for and see if this | 286 // 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... |
553 << "Cannot send empty packets."; | 542 << "Cannot send empty packets."; |
554 | 543 |
555 if (delegate_ == nullptr && original_packet_number != 0) { | 544 if (delegate_ == nullptr && original_packet_number != 0) { |
556 pending_retransmissions_.erase(original_packet_number); | 545 pending_retransmissions_.erase(original_packet_number); |
557 } | 546 } |
558 | 547 |
559 if (pending_timer_transmission_count_ > 0) { | 548 if (pending_timer_transmission_count_ > 0) { |
560 --pending_timer_transmission_count_; | 549 --pending_timer_transmission_count_; |
561 } | 550 } |
562 | 551 |
563 // TODO(ianswett): Remove sent_time, because it's unused. | 552 bool in_flight; |
564 const bool in_flight = send_algorithm_->OnPacketSent( | 553 if (using_pacing_) { |
565 sent_time, unacked_packets_.bytes_in_flight(), packet_number, | 554 in_flight = pacing_sender_.OnPacketSent( |
566 serialized_packet->encrypted_length, has_retransmittable_data); | 555 sent_time, unacked_packets_.bytes_in_flight(), packet_number, |
| 556 serialized_packet->encrypted_length, has_retransmittable_data); |
| 557 } else { |
| 558 in_flight = send_algorithm_->OnPacketSent( |
| 559 sent_time, unacked_packets_.bytes_in_flight(), packet_number, |
| 560 serialized_packet->encrypted_length, has_retransmittable_data); |
| 561 } |
567 | 562 |
568 unacked_packets_.AddSentPacket(serialized_packet, original_packet_number, | 563 unacked_packets_.AddSentPacket(serialized_packet, original_packet_number, |
569 transmission_type, sent_time, in_flight); | 564 transmission_type, sent_time, in_flight); |
570 // Reset the retransmission timer anytime a pending packet is sent. | 565 // Reset the retransmission timer anytime a pending packet is sent. |
571 return in_flight; | 566 return in_flight; |
572 } | 567 } |
573 | 568 |
574 void QuicSentPacketManager::OnRetransmissionTimeout() { | 569 void QuicSentPacketManager::OnRetransmissionTimeout() { |
575 DCHECK(unacked_packets_.HasInFlightPackets()); | 570 DCHECK(unacked_packets_.HasInFlightPackets()); |
576 DCHECK_EQ(0u, pending_timer_transmission_count_); | 571 DCHECK_EQ(0u, pending_timer_transmission_count_); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 return true; | 762 return true; |
768 } | 763 } |
769 | 764 |
770 QuicTime::Delta QuicSentPacketManager::TimeUntilSend(QuicTime now, | 765 QuicTime::Delta QuicSentPacketManager::TimeUntilSend(QuicTime now, |
771 QuicPathId* path_id) { | 766 QuicPathId* path_id) { |
772 QuicTime::Delta delay = QuicTime::Delta::Infinite(); | 767 QuicTime::Delta delay = QuicTime::Delta::Infinite(); |
773 // The TLP logic is entirely contained within QuicSentPacketManager, so the | 768 // The TLP logic is entirely contained within QuicSentPacketManager, so the |
774 // send algorithm does not need to be consulted. | 769 // send algorithm does not need to be consulted. |
775 if (pending_timer_transmission_count_ > 0) { | 770 if (pending_timer_transmission_count_ > 0) { |
776 delay = QuicTime::Delta::Zero(); | 771 delay = QuicTime::Delta::Zero(); |
| 772 } else if (using_pacing_) { |
| 773 delay = |
| 774 pacing_sender_.TimeUntilSend(now, unacked_packets_.bytes_in_flight()); |
777 } else { | 775 } else { |
778 delay = | 776 delay = |
779 send_algorithm_->TimeUntilSend(now, unacked_packets_.bytes_in_flight()); | 777 send_algorithm_->TimeUntilSend(now, unacked_packets_.bytes_in_flight()); |
780 } | 778 } |
781 if (!delay.IsInfinite()) { | 779 if (!delay.IsInfinite()) { |
782 *path_id = path_id_; | 780 *path_id = path_id_; |
783 } | 781 } |
784 return delay; | 782 return delay; |
785 } | 783 } |
786 | 784 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
919 PendingRetransmissionMap::iterator it = pending_retransmissions_.begin(); | 917 PendingRetransmissionMap::iterator it = pending_retransmissions_.begin(); |
920 while (it != pending_retransmissions_.end()) { | 918 while (it != pending_retransmissions_.end()) { |
921 if (unacked_packets_.HasRetransmittableFrames(it->first)) { | 919 if (unacked_packets_.HasRetransmittableFrames(it->first)) { |
922 ++it; | 920 ++it; |
923 continue; | 921 continue; |
924 } | 922 } |
925 it = pending_retransmissions_.erase(it); | 923 it = pending_retransmissions_.erase(it); |
926 } | 924 } |
927 } | 925 } |
928 | 926 |
929 void QuicSentPacketManager::EnablePacing() { | 927 void QuicSentPacketManager::SetSendAlgorithm( |
930 // TODO(ianswett): Replace with a method which wraps the send algorithm in a | 928 CongestionControlType congestion_control_type) { |
931 // pacer every time a new algorithm is set. | 929 SetSendAlgorithm(SendAlgorithmInterface::Create( |
932 if (using_pacing_) { | 930 clock_, &rtt_stats_, congestion_control_type, stats_, |
933 return; | 931 initial_congestion_window_)); |
934 } | 932 } |
935 | 933 |
936 // Set up a pacing sender with a 1 millisecond alarm granularity, the same as | 934 void QuicSentPacketManager::SetSendAlgorithm( |
937 // the default granularity of the Linux kernel's FQ qdisc. | 935 SendAlgorithmInterface* send_algorithm) { |
938 using_pacing_ = true; | 936 send_algorithm_.reset(send_algorithm); |
939 send_algorithm_.reset(new PacingSender(send_algorithm_.release(), | 937 pacing_sender_.set_sender(send_algorithm); |
940 QuicTime::Delta::FromMilliseconds(1), | |
941 kInitialUnpacedBurst)); | |
942 } | 938 } |
943 | 939 |
944 void QuicSentPacketManager::OnConnectionMigration(QuicPathId, | 940 void QuicSentPacketManager::OnConnectionMigration(QuicPathId, |
945 PeerAddressChangeType type) { | 941 PeerAddressChangeType type) { |
946 if (type == PORT_CHANGE || type == IPV4_SUBNET_CHANGE) { | 942 if (type == PORT_CHANGE || type == IPV4_SUBNET_CHANGE) { |
947 // Rtt and cwnd do not need to be reset when the peer address change is | 943 // Rtt and cwnd do not need to be reset when the peer address change is |
948 // considered to be caused by NATs. | 944 // considered to be caused by NATs. |
949 return; | 945 return; |
950 } | 946 } |
951 consecutive_rto_count_ = 0; | 947 consecutive_rto_count_ = 0; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 | 998 |
1003 void QuicSentPacketManager::RemoveObsoletePackets() { | 999 void QuicSentPacketManager::RemoveObsoletePackets() { |
1004 unacked_packets_.RemoveObsoletePackets(); | 1000 unacked_packets_.RemoveObsoletePackets(); |
1005 } | 1001 } |
1006 | 1002 |
1007 void QuicSentPacketManager::OnApplicationLimited() { | 1003 void QuicSentPacketManager::OnApplicationLimited() { |
1008 send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight()); | 1004 send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight()); |
1009 } | 1005 } |
1010 | 1006 |
1011 } // namespace net | 1007 } // namespace net |
OLD | NEW |