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/crypto/crypto_protocol.h" | 10 #include "net/quic/crypto/crypto_protocol.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") | 64 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") |
65 | 65 |
66 QuicSentPacketManager::QuicSentPacketManager(bool is_server, | 66 QuicSentPacketManager::QuicSentPacketManager(bool is_server, |
67 const QuicClock* clock, | 67 const QuicClock* clock, |
68 QuicConnectionStats* stats, | 68 QuicConnectionStats* stats, |
69 CongestionFeedbackType type) | 69 CongestionFeedbackType type) |
70 : unacked_packets_(is_server), | 70 : unacked_packets_(is_server), |
71 is_server_(is_server), | 71 is_server_(is_server), |
72 clock_(clock), | 72 clock_(clock), |
73 stats_(stats), | 73 stats_(stats), |
74 send_algorithm_(SendAlgorithmInterface::Create(clock, type)), | 74 send_algorithm_(SendAlgorithmInterface::Create(clock, type, stats)), |
75 loss_algorithm_(LossDetectionInterface::Create()), | 75 loss_algorithm_(LossDetectionInterface::Create()), |
76 rtt_sample_(QuicTime::Delta::Infinite()), | 76 rtt_sample_(QuicTime::Delta::Infinite()), |
77 largest_observed_(0), | 77 largest_observed_(0), |
78 pending_crypto_packet_count_(0), | 78 pending_crypto_packet_count_(0), |
79 consecutive_rto_count_(0), | 79 consecutive_rto_count_(0), |
80 consecutive_tlp_count_(0), | 80 consecutive_tlp_count_(0), |
81 consecutive_crypto_retransmission_count_(0), | 81 consecutive_crypto_retransmission_count_(0), |
82 max_tail_loss_probes_(kDefaultMaxTailLossProbes), | 82 max_tail_loss_probes_(kDefaultMaxTailLossProbes), |
83 using_pacing_(false) { | 83 using_pacing_(false) { |
84 } | 84 } |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 | 392 |
393 unacked_packets_.SetPending(sequence_number, sent_time, bytes); | 393 unacked_packets_.SetPending(sequence_number, sent_time, bytes); |
394 | 394 |
395 // Reset the retransmission timer anytime a packet is sent in tail loss probe | 395 // Reset the retransmission timer anytime a packet is sent in tail loss probe |
396 // mode or before the crypto handshake has completed. | 396 // mode or before the crypto handshake has completed. |
397 return set_retransmission_timer || GetRetransmissionMode() != RTO_MODE; | 397 return set_retransmission_timer || GetRetransmissionMode() != RTO_MODE; |
398 } | 398 } |
399 | 399 |
400 void QuicSentPacketManager::OnRetransmissionTimeout() { | 400 void QuicSentPacketManager::OnRetransmissionTimeout() { |
401 DCHECK(unacked_packets_.HasPendingPackets()); | 401 DCHECK(unacked_packets_.HasPendingPackets()); |
402 // Handshake retransmission, TLP, and RTO are implemented with a single alarm. | 402 // Handshake retransmission, timer based loss detection, TLP, and RTO are |
403 // The handshake alarm is set when the handshake has not completed, and the | 403 // implemented with a single alarm. The handshake alarm is set when the |
404 // TLP and RTO alarms are set after that. | 404 // handshake has not completed, the loss alarm is set when the loss detection |
| 405 // algorithm says to, and the TLP and RTO alarms are set after that. |
405 // The TLP alarm is always set to run for under an RTO. | 406 // The TLP alarm is always set to run for under an RTO. |
406 switch (GetRetransmissionMode()) { | 407 switch (GetRetransmissionMode()) { |
407 case HANDSHAKE_MODE: | 408 case HANDSHAKE_MODE: |
408 ++stats_->crypto_retransmit_count; | 409 ++stats_->crypto_retransmit_count; |
409 RetransmitCryptoPackets(); | 410 RetransmitCryptoPackets(); |
410 return; | 411 return; |
| 412 case LOSS_MODE: |
| 413 ++stats_->loss_timeout_count; |
| 414 InvokeLossDetection(clock_->Now()); |
| 415 return; |
411 case TLP_MODE: | 416 case TLP_MODE: |
412 // If no tail loss probe can be sent, because there are no retransmittable | 417 // If no tail loss probe can be sent, because there are no retransmittable |
413 // packets, execute a conventional RTO to abandon old packets. | 418 // packets, execute a conventional RTO to abandon old packets. |
414 ++stats_->tlp_count; | 419 ++stats_->tlp_count; |
415 RetransmitOldestPacket(); | 420 RetransmitOldestPacket(); |
416 return; | 421 return; |
417 case RTO_MODE: | 422 case RTO_MODE: |
418 ++stats_->rto_count; | 423 ++stats_->rto_count; |
419 RetransmitAllPackets(); | 424 RetransmitAllPackets(); |
420 return; | 425 return; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 ++consecutive_rto_count_; | 495 ++consecutive_rto_count_; |
491 } | 496 } |
492 } | 497 } |
493 | 498 |
494 QuicSentPacketManager::RetransmissionTimeoutMode | 499 QuicSentPacketManager::RetransmissionTimeoutMode |
495 QuicSentPacketManager::GetRetransmissionMode() const { | 500 QuicSentPacketManager::GetRetransmissionMode() const { |
496 DCHECK(unacked_packets_.HasPendingPackets()); | 501 DCHECK(unacked_packets_.HasPendingPackets()); |
497 if (pending_crypto_packet_count_ > 0) { | 502 if (pending_crypto_packet_count_ > 0) { |
498 return HANDSHAKE_MODE; | 503 return HANDSHAKE_MODE; |
499 } | 504 } |
| 505 if (loss_algorithm_->GetLossTimeout() != QuicTime::Zero()) { |
| 506 return LOSS_MODE; |
| 507 } |
500 if (consecutive_tlp_count_ < max_tail_loss_probes_) { | 508 if (consecutive_tlp_count_ < max_tail_loss_probes_) { |
501 if (unacked_packets_.HasUnackedRetransmittableFrames()) { | 509 if (unacked_packets_.HasUnackedRetransmittableFrames()) { |
502 return TLP_MODE; | 510 return TLP_MODE; |
503 } | 511 } |
504 } | 512 } |
505 return RTO_MODE; | 513 return RTO_MODE; |
506 } | 514 } |
507 | 515 |
508 void QuicSentPacketManager::OnPacketAbandoned( | 516 void QuicSentPacketManager::OnPacketAbandoned( |
509 QuicPacketSequenceNumber sequence_number) { | 517 QuicPacketSequenceNumber sequence_number) { |
510 if (unacked_packets_.IsPending(sequence_number)) { | 518 const QuicUnackedPacketMap::TransmissionInfo& transmission_info = |
511 LOG_IF(DFATAL, unacked_packets_.GetTransmissionInfo( | 519 unacked_packets_.GetTransmissionInfo(sequence_number); |
512 sequence_number).bytes_sent == 0); | 520 if (transmission_info.pending) { |
513 send_algorithm_->OnPacketAbandoned( | 521 LOG_IF(DFATAL, transmission_info.bytes_sent == 0); |
514 sequence_number, | 522 send_algorithm_->OnPacketAbandoned(sequence_number, |
515 unacked_packets_.GetTransmissionInfo(sequence_number).bytes_sent); | 523 transmission_info.bytes_sent); |
516 unacked_packets_.SetNotPending(sequence_number); | 524 unacked_packets_.SetNotPending(sequence_number); |
517 } | 525 } |
518 } | 526 } |
519 | 527 |
520 void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame( | 528 void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame( |
521 const QuicCongestionFeedbackFrame& frame, | 529 const QuicCongestionFeedbackFrame& frame, |
522 const QuicTime& feedback_receive_time) { | 530 const QuicTime& feedback_receive_time) { |
523 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame( | 531 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame( |
524 frame, feedback_receive_time); | 532 frame, feedback_receive_time); |
525 } | 533 } |
(...skipping 21 matching lines...) Expand all Loading... |
547 } | 555 } |
548 | 556 |
549 InvokeLossDetection(ack_receive_time); | 557 InvokeLossDetection(ack_receive_time); |
550 } | 558 } |
551 | 559 |
552 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { | 560 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) { |
553 SequenceNumberSet lost_packets = | 561 SequenceNumberSet lost_packets = |
554 loss_algorithm_->DetectLostPackets(unacked_packets_, | 562 loss_algorithm_->DetectLostPackets(unacked_packets_, |
555 time, | 563 time, |
556 largest_observed_, | 564 largest_observed_, |
557 send_algorithm_->SmoothedRtt()); | 565 send_algorithm_->SmoothedRtt(), |
| 566 rtt_sample_); |
558 for (SequenceNumberSet::const_iterator it = lost_packets.begin(); | 567 for (SequenceNumberSet::const_iterator it = lost_packets.begin(); |
559 it != lost_packets.end(); ++it) { | 568 it != lost_packets.end(); ++it) { |
560 QuicPacketSequenceNumber sequence_number = *it; | 569 QuicPacketSequenceNumber sequence_number = *it; |
561 // TODO(ianswett): If it's expected the FEC packet may repair the loss, it | 570 // TODO(ianswett): If it's expected the FEC packet may repair the loss, it |
562 // should be recorded as a loss to the send algorithm, but not retransmitted | 571 // should be recorded as a loss to the send algorithm, but not retransmitted |
563 // until it's known whether the FEC packet arrived. | 572 // until it's known whether the FEC packet arrived. |
564 ++stats_->packets_lost; | 573 ++stats_->packets_lost; |
565 send_algorithm_->OnPacketLost(sequence_number, time); | 574 send_algorithm_->OnPacketLost(sequence_number, time); |
566 OnPacketAbandoned(sequence_number); | 575 OnPacketAbandoned(sequence_number); |
567 | 576 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 } | 641 } |
633 | 642 |
634 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { | 643 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { |
635 // Don't set the timer if there are no pending packets. | 644 // Don't set the timer if there are no pending packets. |
636 if (!unacked_packets_.HasPendingPackets()) { | 645 if (!unacked_packets_.HasPendingPackets()) { |
637 return QuicTime::Zero(); | 646 return QuicTime::Zero(); |
638 } | 647 } |
639 switch (GetRetransmissionMode()) { | 648 switch (GetRetransmissionMode()) { |
640 case HANDSHAKE_MODE: | 649 case HANDSHAKE_MODE: |
641 return clock_->ApproximateNow().Add(GetCryptoRetransmissionDelay()); | 650 return clock_->ApproximateNow().Add(GetCryptoRetransmissionDelay()); |
| 651 case LOSS_MODE: |
| 652 return loss_algorithm_->GetLossTimeout(); |
642 case TLP_MODE: { | 653 case TLP_MODE: { |
643 // TODO(ianswett): When CWND is available, it would be preferable to | 654 // TODO(ianswett): When CWND is available, it would be preferable to |
644 // set the timer based on the earliest retransmittable packet. | 655 // set the timer based on the earliest retransmittable packet. |
645 // Base the updated timer on the send time of the last packet. | 656 // Base the updated timer on the send time of the last packet. |
646 // TODO(ianswett): I believe this is a subtle mis-implementation of tail | 657 // TODO(ianswett): I believe this is a subtle mis-implementation of tail |
647 // loss probe, since GetLastPacketSentTime actually returns the sent time | 658 // loss probe, since GetLastPacketSentTime actually returns the sent time |
648 // of the last pending packet which still has retransmittable frames. | 659 // of the last pending packet which still has retransmittable frames. |
649 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime(); | 660 const QuicTime sent_time = unacked_packets_.GetLastPacketSentTime(); |
650 const QuicTime tlp_time = sent_time.Add(GetTailLossProbeDelay()); | 661 const QuicTime tlp_time = sent_time.Add(GetTailLossProbeDelay()); |
651 // Ensure the tlp timer never gets set to a time in the past. | 662 // Ensure the tlp timer never gets set to a time in the past. |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 return; | 742 return; |
732 } | 743 } |
733 | 744 |
734 using_pacing_ = true; | 745 using_pacing_ = true; |
735 send_algorithm_.reset( | 746 send_algorithm_.reset( |
736 new PacingSender(send_algorithm_.release(), | 747 new PacingSender(send_algorithm_.release(), |
737 QuicTime::Delta::FromMicroseconds(1))); | 748 QuicTime::Delta::FromMicroseconds(1))); |
738 } | 749 } |
739 | 750 |
740 } // namespace net | 751 } // namespace net |
OLD | NEW |