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" |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 bytes, | 460 bytes, |
461 has_retransmittable_data); | 461 has_retransmittable_data); |
462 unacked_packets_.SetSent(sequence_number, sent_time, bytes, in_flight); | 462 unacked_packets_.SetSent(sequence_number, sent_time, bytes, in_flight); |
463 | 463 |
464 // Reset the retransmission timer anytime a pending packet is sent. | 464 // Reset the retransmission timer anytime a pending packet is sent. |
465 return in_flight; | 465 return in_flight; |
466 } | 466 } |
467 | 467 |
468 void QuicSentPacketManager::OnRetransmissionTimeout() { | 468 void QuicSentPacketManager::OnRetransmissionTimeout() { |
469 DCHECK(unacked_packets_.HasInFlightPackets()); | 469 DCHECK(unacked_packets_.HasInFlightPackets()); |
| 470 DCHECK(!pending_tlp_transmission_); |
470 // Handshake retransmission, timer based loss detection, TLP, and RTO are | 471 // Handshake retransmission, timer based loss detection, TLP, and RTO are |
471 // implemented with a single alarm. The handshake alarm is set when the | 472 // implemented with a single alarm. The handshake alarm is set when the |
472 // handshake has not completed, the loss alarm is set when the loss detection | 473 // handshake has not completed, the loss alarm is set when the loss detection |
473 // algorithm says to, and the TLP and RTO alarms are set after that. | 474 // algorithm says to, and the TLP and RTO alarms are set after that. |
474 // The TLP alarm is always set to run for under an RTO. | 475 // The TLP alarm is always set to run for under an RTO. |
475 switch (GetRetransmissionMode()) { | 476 switch (GetRetransmissionMode()) { |
476 case HANDSHAKE_MODE: | 477 case HANDSHAKE_MODE: |
477 ++stats_->crypto_retransmit_count; | 478 ++stats_->crypto_retransmit_count; |
478 RetransmitCryptoPackets(); | 479 RetransmitCryptoPackets(); |
479 return; | 480 return; |
480 case LOSS_MODE: { | 481 case LOSS_MODE: { |
481 ++stats_->loss_timeout_count; | 482 ++stats_->loss_timeout_count; |
482 QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight(); | 483 QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight(); |
483 InvokeLossDetection(clock_->Now()); | 484 InvokeLossDetection(clock_->Now()); |
484 MaybeInvokeCongestionEvent(false, bytes_in_flight); | 485 MaybeInvokeCongestionEvent(false, bytes_in_flight); |
485 return; | 486 return; |
486 } | 487 } |
487 case TLP_MODE: | 488 case TLP_MODE: |
488 // If no tail loss probe can be sent, because there are no retransmittable | 489 // If no tail loss probe can be sent, because there are no retransmittable |
489 // packets, execute a conventional RTO to abandon old packets. | 490 // packets, execute a conventional RTO to abandon old packets. |
490 ++stats_->tlp_count; | 491 ++stats_->tlp_count; |
| 492 ++consecutive_tlp_count_; |
491 pending_tlp_transmission_ = true; | 493 pending_tlp_transmission_ = true; |
492 RetransmitOldestPacket(); | 494 // TLPs prefer sending new data instead of retransmitting data, so |
| 495 // give the connection a chance to write before completing the TLP. |
493 return; | 496 return; |
494 case RTO_MODE: | 497 case RTO_MODE: |
495 ++stats_->rto_count; | 498 ++stats_->rto_count; |
496 RetransmitAllPackets(); | 499 RetransmitAllPackets(); |
497 return; | 500 return; |
498 } | 501 } |
499 } | 502 } |
500 | 503 |
501 void QuicSentPacketManager::RetransmitCryptoPackets() { | 504 void QuicSentPacketManager::RetransmitCryptoPackets() { |
502 DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode()); | 505 DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode()); |
(...skipping 10 matching lines...) Expand all Loading... |
513 if (!it->second.in_flight || frames == NULL || | 516 if (!it->second.in_flight || frames == NULL || |
514 frames->HasCryptoHandshake() != IS_HANDSHAKE) { | 517 frames->HasCryptoHandshake() != IS_HANDSHAKE) { |
515 continue; | 518 continue; |
516 } | 519 } |
517 packet_retransmitted = true; | 520 packet_retransmitted = true; |
518 MarkForRetransmission(sequence_number, HANDSHAKE_RETRANSMISSION); | 521 MarkForRetransmission(sequence_number, HANDSHAKE_RETRANSMISSION); |
519 } | 522 } |
520 DCHECK(packet_retransmitted) << "No crypto packets found to retransmit."; | 523 DCHECK(packet_retransmitted) << "No crypto packets found to retransmit."; |
521 } | 524 } |
522 | 525 |
523 void QuicSentPacketManager::RetransmitOldestPacket() { | 526 bool QuicSentPacketManager::MaybeRetransmitTailLossProbe() { |
524 DCHECK_EQ(TLP_MODE, GetRetransmissionMode()); | 527 if (!pending_tlp_transmission_) { |
525 ++consecutive_tlp_count_; | 528 return false; |
| 529 } |
526 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 530 for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
527 it != unacked_packets_.end(); ++it) { | 531 it != unacked_packets_.end(); ++it) { |
528 QuicPacketSequenceNumber sequence_number = it->first; | 532 QuicPacketSequenceNumber sequence_number = it->first; |
529 const RetransmittableFrames* frames = it->second.retransmittable_frames; | 533 const RetransmittableFrames* frames = it->second.retransmittable_frames; |
530 // Only retransmit frames which are in flight, and therefore have been sent. | 534 // Only retransmit frames which are in flight, and therefore have been sent. |
531 if (!it->second.in_flight || frames == NULL) { | 535 if (!it->second.in_flight || frames == NULL) { |
532 continue; | 536 continue; |
533 } | 537 } |
534 DCHECK_NE(IS_HANDSHAKE, frames->HasCryptoHandshake()); | 538 DCHECK_NE(IS_HANDSHAKE, frames->HasCryptoHandshake()); |
535 MarkForRetransmission(sequence_number, TLP_RETRANSMISSION); | 539 MarkForRetransmission(sequence_number, TLP_RETRANSMISSION); |
536 return; | 540 return true; |
537 } | 541 } |
538 DLOG(FATAL) | 542 DLOG(FATAL) |
539 << "No retransmittable packets, so RetransmitOldestPacket failed."; | 543 << "No retransmittable packets, so RetransmitOldestPacket failed."; |
| 544 return false; |
540 } | 545 } |
541 | 546 |
542 void QuicSentPacketManager::RetransmitAllPackets() { | 547 void QuicSentPacketManager::RetransmitAllPackets() { |
543 DVLOG(1) << "RetransmitAllPackets() called with " | 548 DVLOG(1) << "RetransmitAllPackets() called with " |
544 << unacked_packets_.GetNumUnackedPackets() << " unacked packets."; | 549 << unacked_packets_.GetNumUnackedPackets() << " unacked packets."; |
545 // Request retransmission of all retransmittable packets when the RTO | 550 // Request retransmission of all retransmittable packets when the RTO |
546 // fires, and let the congestion manager decide how many to send | 551 // fires, and let the congestion manager decide how many to send |
547 // immediately and the remaining packets will be queued. | 552 // immediately and the remaining packets will be queued. |
548 // Abandon any non-retransmittable packets that are sufficiently old. | 553 // Abandon any non-retransmittable packets that are sufficiently old. |
549 bool packets_retransmitted = false; | 554 bool packets_retransmitted = false; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 // There may be a value in making this delay adaptive with the help of | 669 // There may be a value in making this delay adaptive with the help of |
665 // the sender and a signaling mechanism -- if the sender uses a | 670 // the sender and a signaling mechanism -- if the sender uses a |
666 // different MinRTO, we may get spurious retransmissions. May not have | 671 // different MinRTO, we may get spurious retransmissions. May not have |
667 // any benefits, but if the delayed ack becomes a significant source | 672 // any benefits, but if the delayed ack becomes a significant source |
668 // of (likely, tail) latency, then consider such a mechanism. | 673 // of (likely, tail) latency, then consider such a mechanism. |
669 const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const { | 674 const QuicTime::Delta QuicSentPacketManager::DelayedAckTime() const { |
670 return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2); | 675 return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2); |
671 } | 676 } |
672 | 677 |
673 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { | 678 const QuicTime QuicSentPacketManager::GetRetransmissionTime() const { |
674 // Don't set the timer if there are no packets in flight. | 679 // Don't set the timer if there are no packets in flight or we've already |
675 if (!unacked_packets_.HasInFlightPackets()) { | 680 // queued a tlp transmission and it hasn't been sent yet. |
| 681 if (!unacked_packets_.HasInFlightPackets() || pending_tlp_transmission_) { |
676 return QuicTime::Zero(); | 682 return QuicTime::Zero(); |
677 } | 683 } |
678 switch (GetRetransmissionMode()) { | 684 switch (GetRetransmissionMode()) { |
679 case HANDSHAKE_MODE: | 685 case HANDSHAKE_MODE: |
680 return clock_->ApproximateNow().Add(GetCryptoRetransmissionDelay()); | 686 return clock_->ApproximateNow().Add(GetCryptoRetransmissionDelay()); |
681 case LOSS_MODE: | 687 case LOSS_MODE: |
682 return loss_algorithm_->GetLossTimeout(); | 688 return loss_algorithm_->GetLossTimeout(); |
683 case TLP_MODE: { | 689 case TLP_MODE: { |
684 // TODO(ianswett): When CWND is available, it would be preferable to | 690 // TODO(ianswett): When CWND is available, it would be preferable to |
685 // set the timer based on the earliest retransmittable packet. | 691 // set the timer based on the earliest retransmittable packet. |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 } | 776 } |
771 | 777 |
772 // Set up a pacing sender with a 5 millisecond alarm granularity. | 778 // Set up a pacing sender with a 5 millisecond alarm granularity. |
773 using_pacing_ = true; | 779 using_pacing_ = true; |
774 send_algorithm_.reset( | 780 send_algorithm_.reset( |
775 new PacingSender(send_algorithm_.release(), | 781 new PacingSender(send_algorithm_.release(), |
776 QuicTime::Delta::FromMilliseconds(5))); | 782 QuicTime::Delta::FromMilliseconds(5))); |
777 } | 783 } |
778 | 784 |
779 } // namespace net | 785 } // namespace net |
OLD | NEW |