| 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" |
| 11 #include "net/quic/congestion_control/general_loss_algorithm.h" | 11 #include "net/quic/congestion_control/general_loss_algorithm.h" |
| 12 #include "net/quic/congestion_control/pacing_sender.h" | 12 #include "net/quic/congestion_control/pacing_sender.h" |
| 13 #include "net/quic/crypto/crypto_protocol.h" | 13 #include "net/quic/crypto/crypto_protocol.h" |
| 14 #include "net/quic/proto/cached_network_parameters.pb.h" | |
| 15 #include "net/quic/quic_bug_tracker.h" | 14 #include "net/quic/quic_bug_tracker.h" |
| 16 #include "net/quic/quic_connection_stats.h" | 15 #include "net/quic/quic_connection_stats.h" |
| 17 #include "net/quic/quic_flags.h" | 16 #include "net/quic/quic_flags.h" |
| 18 #include "net/quic/quic_utils_chromium.h" | 17 #include "net/quic/quic_utils_chromium.h" |
| 19 | 18 |
| 20 using std::max; | 19 using std::max; |
| 21 using std::min; | 20 using std::min; |
| 22 using std::pair; | 21 using std::pair; |
| 23 | 22 |
| 24 namespace net { | 23 namespace net { |
| 25 | 24 |
| 26 // The length of the recent min rtt window in seconds. Windowing is disabled for | 25 // The length of the recent min rtt window in seconds. Windowing is disabled for |
| 27 // values less than or equal to 0. | 26 // values less than or equal to 0. |
| 28 int32_t FLAGS_quic_recent_min_rtt_window_s = 60; | 27 int32_t FLAGS_quic_recent_min_rtt_window_s = 60; |
| 29 | 28 |
| 30 namespace { | 29 namespace { |
| 31 static const int64_t kDefaultRetransmissionTimeMs = 500; | 30 static const int64_t kDefaultRetransmissionTimeMs = 500; |
| 32 // TCP RFC calls for 1 second RTO however Linux differs from this default and | |
| 33 // define the minimum RTO to 200ms, we will use the same until we have data to | |
| 34 // support a higher or lower value. | |
| 35 static const int64_t kMinRetransmissionTimeMs = 200; | |
| 36 static const int64_t kMaxRetransmissionTimeMs = 60000; | 31 static const int64_t kMaxRetransmissionTimeMs = 60000; |
| 37 // Maximum number of exponential backoffs used for RTO timeouts. | 32 // Maximum number of exponential backoffs used for RTO timeouts. |
| 38 static const size_t kMaxRetransmissions = 10; | 33 static const size_t kMaxRetransmissions = 10; |
| 39 // Maximum number of packets retransmitted upon an RTO. | 34 // Maximum number of packets retransmitted upon an RTO. |
| 40 static const size_t kMaxRetransmissionsOnTimeout = 2; | 35 static const size_t kMaxRetransmissionsOnTimeout = 2; |
| 41 // Minimum number of consecutive RTOs before path is considered to be degrading. | 36 // Minimum number of consecutive RTOs before path is considered to be degrading. |
| 42 const size_t kMinTimeoutsBeforePathDegrading = 2; | 37 const size_t kMinTimeoutsBeforePathDegrading = 2; |
| 43 | 38 |
| 44 // Ensure the handshake timer isnt't faster than 10ms. | 39 // Ensure the handshake timer isnt't faster than 10ms. |
| 45 // This limits the tenth retransmitted packet to 10s after the initial CHLO. | 40 // This limits the tenth retransmitted packet to 10s after the initial CHLO. |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 } | 207 } |
| 213 } | 208 } |
| 214 | 209 |
| 215 void QuicSentPacketManager::SetMaxPacingRate(QuicBandwidth max_pacing_rate) { | 210 void QuicSentPacketManager::SetMaxPacingRate(QuicBandwidth max_pacing_rate) { |
| 216 if (FLAGS_quic_max_pacing_rate && using_pacing_) { | 211 if (FLAGS_quic_max_pacing_rate && using_pacing_) { |
| 217 static_cast<PacingSender*>(send_algorithm_.get()) | 212 static_cast<PacingSender*>(send_algorithm_.get()) |
| 218 ->SetMaxPacingRate(max_pacing_rate); | 213 ->SetMaxPacingRate(max_pacing_rate); |
| 219 } | 214 } |
| 220 } | 215 } |
| 221 | 216 |
| 217 void QuicSentPacketManager::SetHandshakeConfirmed() { |
| 218 handshake_confirmed_ = true; |
| 219 } |
| 220 |
| 222 void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame, | 221 void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame, |
| 223 QuicTime ack_receive_time) { | 222 QuicTime ack_receive_time) { |
| 224 DCHECK_LE(ack_frame.largest_observed, unacked_packets_.largest_sent_packet()); | 223 DCHECK_LE(ack_frame.largest_observed, unacked_packets_.largest_sent_packet()); |
| 225 QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight(); | 224 QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight(); |
| 226 UpdatePacketInformationReceivedByPeer(ack_frame); | 225 UpdatePacketInformationReceivedByPeer(ack_frame); |
| 227 bool rtt_updated = MaybeUpdateRTT(ack_frame, ack_receive_time); | 226 bool rtt_updated = MaybeUpdateRTT(ack_frame, ack_receive_time); |
| 228 DCHECK_GE(ack_frame.largest_observed, unacked_packets_.largest_observed()); | 227 DCHECK_GE(ack_frame.largest_observed, unacked_packets_.largest_observed()); |
| 229 unacked_packets_.IncreaseLargestObserved(ack_frame.largest_observed); | 228 unacked_packets_.IncreaseLargestObserved(ack_frame.largest_observed); |
| 230 | 229 |
| 231 HandleAckForSentPackets(ack_frame); | 230 HandleAckForSentPackets(ack_frame); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 pending_retransmissions_.front().first > largest_newly_acked_ && | 270 pending_retransmissions_.front().first > largest_newly_acked_ && |
| 272 pending_retransmissions_.front().second == LOSS_RETRANSMISSION) { | 271 pending_retransmissions_.front().second == LOSS_RETRANSMISSION) { |
| 273 // Cancel any pending retransmissions larger than largest_newly_acked_. | 272 // Cancel any pending retransmissions larger than largest_newly_acked_. |
| 274 unacked_packets_.RestoreToInFlight(pending_retransmissions_.front().first); | 273 unacked_packets_.RestoreToInFlight(pending_retransmissions_.front().first); |
| 275 pending_retransmissions_.erase(pending_retransmissions_.begin()); | 274 pending_retransmissions_.erase(pending_retransmissions_.begin()); |
| 276 } | 275 } |
| 277 | 276 |
| 278 if (debug_delegate_ != nullptr) { | 277 if (debug_delegate_ != nullptr) { |
| 279 debug_delegate_->OnIncomingAck(ack_frame, ack_receive_time, | 278 debug_delegate_->OnIncomingAck(ack_frame, ack_receive_time, |
| 280 unacked_packets_.largest_observed(), | 279 unacked_packets_.largest_observed(), |
| 281 rtt_updated, GetLeastUnacked()); | 280 rtt_updated, GetLeastUnacked(path_id_)); |
| 282 } | 281 } |
| 283 } | 282 } |
| 284 | 283 |
| 285 void QuicSentPacketManager::UpdatePacketInformationReceivedByPeer( | 284 void QuicSentPacketManager::UpdatePacketInformationReceivedByPeer( |
| 286 const QuicAckFrame& ack_frame) { | 285 const QuicAckFrame& ack_frame) { |
| 287 if (ack_frame.packets.Empty()) { | 286 if (ack_frame.packets.Empty()) { |
| 288 least_packet_awaited_by_peer_ = ack_frame.largest_observed + 1; | 287 least_packet_awaited_by_peer_ = ack_frame.largest_observed + 1; |
| 289 } else { | 288 } else { |
| 290 least_packet_awaited_by_peer_ = ack_frame.packets.Min(); | 289 least_packet_awaited_by_peer_ = ack_frame.packets.Min(); |
| 291 } | 290 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 packets_acked_.push_back(std::make_pair(packet_number, it->bytes_sent)); | 345 packets_acked_.push_back(std::make_pair(packet_number, it->bytes_sent)); |
| 347 } else if (FLAGS_quic_loss_recovery_use_largest_acked && | 346 } else if (FLAGS_quic_loss_recovery_use_largest_acked && |
| 348 !it->is_unackable) { | 347 !it->is_unackable) { |
| 349 largest_newly_acked_ = packet_number; | 348 largest_newly_acked_ = packet_number; |
| 350 } | 349 } |
| 351 MarkPacketHandled(packet_number, &(*it), ack_delay_time); | 350 MarkPacketHandled(packet_number, &(*it), ack_delay_time); |
| 352 } | 351 } |
| 353 } | 352 } |
| 354 | 353 |
| 355 bool QuicSentPacketManager::HasRetransmittableFrames( | 354 bool QuicSentPacketManager::HasRetransmittableFrames( |
| 355 QuicPathId, |
| 356 QuicPacketNumber packet_number) const { | 356 QuicPacketNumber packet_number) const { |
| 357 return unacked_packets_.HasRetransmittableFrames(packet_number); | 357 return unacked_packets_.HasRetransmittableFrames(packet_number); |
| 358 } | 358 } |
| 359 | 359 |
| 360 void QuicSentPacketManager::RetransmitUnackedPackets( | 360 void QuicSentPacketManager::RetransmitUnackedPackets( |
| 361 TransmissionType retransmission_type) { | 361 TransmissionType retransmission_type) { |
| 362 DCHECK(retransmission_type == ALL_UNACKED_RETRANSMISSION || | 362 DCHECK(retransmission_type == ALL_UNACKED_RETRANSMISSION || |
| 363 retransmission_type == ALL_INITIAL_RETRANSMISSION); | 363 retransmission_type == ALL_INITIAL_RETRANSMISSION); |
| 364 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); | 364 QuicPacketNumber packet_number = unacked_packets_.GetLeastUnacked(); |
| 365 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 365 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 } | 552 } |
| 553 } | 553 } |
| 554 | 554 |
| 555 unacked_packets_.RemoveFromInFlight(info); | 555 unacked_packets_.RemoveFromInFlight(info); |
| 556 unacked_packets_.RemoveRetransmittability(info); | 556 unacked_packets_.RemoveRetransmittability(info); |
| 557 if (FLAGS_quic_loss_recovery_use_largest_acked) { | 557 if (FLAGS_quic_loss_recovery_use_largest_acked) { |
| 558 info->is_unackable = true; | 558 info->is_unackable = true; |
| 559 } | 559 } |
| 560 } | 560 } |
| 561 | 561 |
| 562 bool QuicSentPacketManager::IsUnacked(QuicPacketNumber packet_number) const { | 562 bool QuicSentPacketManager::IsUnacked(QuicPathId, |
| 563 QuicPacketNumber packet_number) const { |
| 563 return unacked_packets_.IsUnacked(packet_number); | 564 return unacked_packets_.IsUnacked(packet_number); |
| 564 } | 565 } |
| 565 | 566 |
| 566 bool QuicSentPacketManager::HasUnackedPackets() const { | 567 bool QuicSentPacketManager::HasUnackedPackets() const { |
| 567 return unacked_packets_.HasUnackedPackets(); | 568 return unacked_packets_.HasUnackedPackets(); |
| 568 } | 569 } |
| 569 | 570 |
| 570 QuicPacketNumber QuicSentPacketManager::GetLeastUnacked() const { | 571 QuicPacketNumber QuicSentPacketManager::GetLeastUnacked(QuicPathId) const { |
| 571 return unacked_packets_.GetLeastUnacked(); | 572 return unacked_packets_.GetLeastUnacked(); |
| 572 } | 573 } |
| 573 | 574 |
| 574 bool QuicSentPacketManager::OnPacketSent( | 575 bool QuicSentPacketManager::OnPacketSent( |
| 575 SerializedPacket* serialized_packet, | 576 SerializedPacket* serialized_packet, |
| 576 QuicPathId /*original_path_id*/, | 577 QuicPathId /*original_path_id*/, |
| 577 QuicPacketNumber original_packet_number, | 578 QuicPacketNumber original_packet_number, |
| 578 QuicTime sent_time, | 579 QuicTime sent_time, |
| 579 TransmissionType transmission_type, | 580 TransmissionType transmission_type, |
| 580 HasRetransmittableData has_retransmittable_data) { | 581 HasRetransmittableData has_retransmittable_data) { |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 | 789 |
| 789 QuicTime::Delta send_delta = | 790 QuicTime::Delta send_delta = |
| 790 ack_receive_time.Subtract(transmission_info.sent_time); | 791 ack_receive_time.Subtract(transmission_info.sent_time); |
| 791 rtt_stats_.UpdateRtt(send_delta, ack_frame.ack_delay_time, ack_receive_time); | 792 rtt_stats_.UpdateRtt(send_delta, ack_frame.ack_delay_time, ack_receive_time); |
| 792 | 793 |
| 793 return true; | 794 return true; |
| 794 } | 795 } |
| 795 | 796 |
| 796 QuicTime::Delta QuicSentPacketManager::TimeUntilSend( | 797 QuicTime::Delta QuicSentPacketManager::TimeUntilSend( |
| 797 QuicTime now, | 798 QuicTime now, |
| 798 HasRetransmittableData retransmittable) { | 799 HasRetransmittableData retransmittable, |
| 800 QuicPathId* path_id) { |
| 801 QuicTime::Delta delay = QuicTime::Delta::Infinite(); |
| 799 // The TLP logic is entirely contained within QuicSentPacketManager, so the | 802 // The TLP logic is entirely contained within QuicSentPacketManager, so the |
| 800 // send algorithm does not need to be consulted. | 803 // send algorithm does not need to be consulted. |
| 801 if (pending_timer_transmission_count_ > 0) { | 804 if (pending_timer_transmission_count_ > 0) { |
| 802 return QuicTime::Delta::Zero(); | 805 delay = QuicTime::Delta::Zero(); |
| 806 } else { |
| 807 delay = |
| 808 send_algorithm_->TimeUntilSend(now, unacked_packets_.bytes_in_flight()); |
| 803 } | 809 } |
| 804 return send_algorithm_->TimeUntilSend(now, | 810 if (!delay.IsInfinite()) { |
| 805 unacked_packets_.bytes_in_flight()); | 811 *path_id = path_id_; |
| 806 } | 812 } |
| 807 | 813 return delay; |
| 808 // Uses a 25ms delayed ack timer. Also helps with better signaling | |
| 809 // in low-bandwidth (< ~384 kbps), where an ack is sent per packet. | |
| 810 // Ensures that the Delayed Ack timer is always set to a value lesser | |
| 811 // than the retransmission timer's minimum value (MinRTO). We want the | |
| 812 // delayed ack to get back to the QUIC peer before the sender's | |
| 813 // retransmission timer triggers. Since we do not know the | |
| 814 // reverse-path one-way delay, we assume equal delays for forward and | |
| 815 // reverse paths, and ensure that the timer is set to less than half | |
| 816 // of the MinRTO. | |
| 817 // There may be a value in making this delay adaptive with the help of | |
| 818 // the sender and a signaling mechanism -- if the sender uses a | |
| 819 // different MinRTO, we may get spurious retransmissions. May not have | |
| 820 // any benefits, but if the delayed ack becomes a significant source | |
| 821 // of (likely, tail) latency, then consider such a mechanism. | |
| 822 const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const { | |
| 823 return QuicTime::Delta::FromMilliseconds( | |
| 824 min(kMaxDelayedAckTimeMs, kMinRetransmissionTimeMs / 2)); | |
| 825 } | 814 } |
| 826 | 815 |
| 827 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { | 816 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { |
| 828 // Don't set the timer if there are no packets in flight or we've already | 817 // Don't set the timer if there are no packets in flight or we've already |
| 829 // queued a tlp transmission and it hasn't been sent yet. | 818 // queued a tlp transmission and it hasn't been sent yet. |
| 830 if (!unacked_packets_.HasInFlightPackets() || | 819 if (!unacked_packets_.HasInFlightPackets() || |
| 831 pending_timer_transmission_count_ > 0) { | 820 pending_timer_transmission_count_ > 0) { |
| 832 return QuicTime::Zero(); | 821 return QuicTime::Zero(); |
| 833 } | 822 } |
| 834 switch (GetRetransmissionMode()) { | 823 switch (GetRetransmissionMode()) { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 } | 937 } |
| 949 | 938 |
| 950 void QuicSentPacketManager::CancelRetransmissionsForStream( | 939 void QuicSentPacketManager::CancelRetransmissionsForStream( |
| 951 QuicStreamId stream_id) { | 940 QuicStreamId stream_id) { |
| 952 unacked_packets_.CancelRetransmissionsForStream(stream_id); | 941 unacked_packets_.CancelRetransmissionsForStream(stream_id); |
| 953 if (delegate_ != nullptr) { | 942 if (delegate_ != nullptr) { |
| 954 return; | 943 return; |
| 955 } | 944 } |
| 956 PendingRetransmissionMap::iterator it = pending_retransmissions_.begin(); | 945 PendingRetransmissionMap::iterator it = pending_retransmissions_.begin(); |
| 957 while (it != pending_retransmissions_.end()) { | 946 while (it != pending_retransmissions_.end()) { |
| 958 if (HasRetransmittableFrames(it->first)) { | 947 if (HasRetransmittableFrames(path_id_, it->first)) { |
| 959 ++it; | 948 ++it; |
| 960 continue; | 949 continue; |
| 961 } | 950 } |
| 962 it = pending_retransmissions_.erase(it); | 951 it = pending_retransmissions_.erase(it); |
| 963 } | 952 } |
| 964 } | 953 } |
| 965 | 954 |
| 966 void QuicSentPacketManager::EnablePacing() { | 955 void QuicSentPacketManager::EnablePacing() { |
| 967 // TODO(ianswett): Replace with a method which wraps the send algorithm in a | 956 // TODO(ianswett): Replace with a method which wraps the send algorithm in a |
| 968 // pacer every time a new algorithm is set. | 957 // pacer every time a new algorithm is set. |
| 969 if (using_pacing_) { | 958 if (using_pacing_) { |
| 970 return; | 959 return; |
| 971 } | 960 } |
| 972 | 961 |
| 973 // Set up a pacing sender with a 1 millisecond alarm granularity, the same as | 962 // Set up a pacing sender with a 1 millisecond alarm granularity, the same as |
| 974 // the default granularity of the Linux kernel's FQ qdisc. | 963 // the default granularity of the Linux kernel's FQ qdisc. |
| 975 using_pacing_ = true; | 964 using_pacing_ = true; |
| 976 send_algorithm_.reset(new PacingSender(send_algorithm_.release(), | 965 send_algorithm_.reset(new PacingSender(send_algorithm_.release(), |
| 977 QuicTime::Delta::FromMilliseconds(1), | 966 QuicTime::Delta::FromMilliseconds(1), |
| 978 kInitialUnpacedBurst)); | 967 kInitialUnpacedBurst)); |
| 979 } | 968 } |
| 980 | 969 |
| 981 void QuicSentPacketManager::OnConnectionMigration(PeerAddressChangeType type) { | 970 void QuicSentPacketManager::OnConnectionMigration(QuicPathId, |
| 971 PeerAddressChangeType type) { |
| 982 if (type == PORT_CHANGE || type == IPV4_SUBNET_CHANGE) { | 972 if (type == PORT_CHANGE || type == IPV4_SUBNET_CHANGE) { |
| 983 // Rtt and cwnd do not need to be reset when the peer address change is | 973 // Rtt and cwnd do not need to be reset when the peer address change is |
| 984 // considered to be caused by NATs. | 974 // considered to be caused by NATs. |
| 985 return; | 975 return; |
| 986 } | 976 } |
| 987 consecutive_rto_count_ = 0; | 977 consecutive_rto_count_ = 0; |
| 988 consecutive_tlp_count_ = 0; | 978 consecutive_tlp_count_ = 0; |
| 989 rtt_stats_.OnConnectionMigration(); | 979 rtt_stats_.OnConnectionMigration(); |
| 990 send_algorithm_->OnConnectionMigration(); | 980 send_algorithm_->OnConnectionMigration(); |
| 991 } | 981 } |
| 992 | 982 |
| 983 bool QuicSentPacketManager::IsHandshakeConfirmed() const { |
| 984 return handshake_confirmed_; |
| 985 } |
| 986 |
| 987 void QuicSentPacketManager::SetDebugDelegate(DebugDelegate* debug_delegate) { |
| 988 debug_delegate_ = debug_delegate; |
| 989 } |
| 990 |
| 991 QuicPacketNumber QuicSentPacketManager::GetLargestObserved(QuicPathId) const { |
| 992 return unacked_packets_.largest_observed(); |
| 993 } |
| 994 |
| 995 QuicPacketNumber QuicSentPacketManager::GetLargestSentPacket(QuicPathId) const { |
| 996 return unacked_packets_.largest_sent_packet(); |
| 997 } |
| 998 |
| 999 QuicPacketNumber QuicSentPacketManager::GetLeastPacketAwaitedByPeer( |
| 1000 QuicPathId) const { |
| 1001 return least_packet_awaited_by_peer_; |
| 1002 } |
| 1003 |
| 1004 void QuicSentPacketManager::SetNetworkChangeVisitor( |
| 1005 NetworkChangeVisitor* visitor) { |
| 1006 DCHECK(!network_change_visitor_); |
| 1007 DCHECK(visitor); |
| 1008 network_change_visitor_ = visitor; |
| 1009 } |
| 1010 |
| 993 bool QuicSentPacketManager::InSlowStart() const { | 1011 bool QuicSentPacketManager::InSlowStart() const { |
| 994 return send_algorithm_->InSlowStart(); | 1012 return send_algorithm_->InSlowStart(); |
| 995 } | 1013 } |
| 996 | 1014 |
| 1015 size_t QuicSentPacketManager::GetConsecutiveRtoCount() const { |
| 1016 return consecutive_rto_count_; |
| 1017 } |
| 1018 |
| 1019 size_t QuicSentPacketManager::GetConsecutiveTlpCount() const { |
| 1020 return consecutive_tlp_count_; |
| 1021 } |
| 1022 |
| 997 TransmissionInfo* QuicSentPacketManager::GetMutableTransmissionInfo( | 1023 TransmissionInfo* QuicSentPacketManager::GetMutableTransmissionInfo( |
| 998 QuicPacketNumber packet_number) { | 1024 QuicPacketNumber packet_number) { |
| 999 return unacked_packets_.GetMutableTransmissionInfo(packet_number); | 1025 return unacked_packets_.GetMutableTransmissionInfo(packet_number); |
| 1000 } | 1026 } |
| 1001 | 1027 |
| 1002 void QuicSentPacketManager::RemoveObsoletePackets() { | 1028 void QuicSentPacketManager::RemoveObsoletePackets() { |
| 1003 unacked_packets_.RemoveObsoletePackets(); | 1029 unacked_packets_.RemoveObsoletePackets(); |
| 1004 } | 1030 } |
| 1005 | 1031 |
| 1006 } // namespace net | 1032 } // namespace net |
| OLD | NEW |