| 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 27 matching lines...) Expand all Loading... |
| 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 // Ensure the handshake timer isnt't faster than 25ms. | 41 // Ensure the handshake timer isnt't faster than 25ms. |
| 42 static const int64_t kConservativeMinHandshakeTimeoutMs = kMaxDelayedAckTimeMs; | 42 static const int64_t kConservativeMinHandshakeTimeoutMs = kMaxDelayedAckTimeMs; |
| 43 | 43 |
| 44 // Sends up to two tail loss probes before firing an RTO, | 44 // Sends up to two tail loss probes before firing an RTO, |
| 45 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. | 45 // per draft RFC draft-dukkipati-tcpm-tcp-loss-probe. |
| 46 static const size_t kDefaultMaxTailLossProbes = 2; | 46 static const size_t kDefaultMaxTailLossProbes = 2; |
| 47 | 47 |
| 48 bool HasCryptoHandshake(const TransmissionInfo& transmission_info) { | 48 bool HasCryptoHandshake(const QuicTransmissionInfo& transmission_info) { |
| 49 DCHECK(!transmission_info.has_crypto_handshake || | 49 DCHECK(!transmission_info.has_crypto_handshake || |
| 50 !transmission_info.retransmittable_frames.empty()); | 50 !transmission_info.retransmittable_frames.empty()); |
| 51 return transmission_info.has_crypto_handshake; | 51 return transmission_info.has_crypto_handshake; |
| 52 } | 52 } |
| 53 | 53 |
| 54 } // namespace | 54 } // namespace |
| 55 | 55 |
| 56 #define ENDPOINT \ | 56 #define ENDPOINT \ |
| 57 (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ") | 57 (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ") |
| 58 | 58 |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 } | 397 } |
| 398 unacked_packets_.RemoveFromInFlight(packet_number); | 398 unacked_packets_.RemoveFromInFlight(packet_number); |
| 399 unacked_packets_.RemoveRetransmittability(packet_number); | 399 unacked_packets_.RemoveRetransmittability(packet_number); |
| 400 } | 400 } |
| 401 } | 401 } |
| 402 } | 402 } |
| 403 | 403 |
| 404 void QuicSentPacketManager::MarkForRetransmission( | 404 void QuicSentPacketManager::MarkForRetransmission( |
| 405 QuicPacketNumber packet_number, | 405 QuicPacketNumber packet_number, |
| 406 TransmissionType transmission_type) { | 406 TransmissionType transmission_type) { |
| 407 const TransmissionInfo& transmission_info = | 407 const QuicTransmissionInfo& transmission_info = |
| 408 unacked_packets_.GetTransmissionInfo(packet_number); | 408 unacked_packets_.GetTransmissionInfo(packet_number); |
| 409 QUIC_BUG_IF(transmission_info.retransmittable_frames.empty()); | 409 QUIC_BUG_IF(transmission_info.retransmittable_frames.empty()); |
| 410 // Both TLP and the new RTO leave the packets in flight and let the loss | 410 // Both TLP and the new RTO leave the packets in flight and let the loss |
| 411 // detection decide if packets are lost. | 411 // detection decide if packets are lost. |
| 412 if (transmission_type != TLP_RETRANSMISSION && | 412 if (transmission_type != TLP_RETRANSMISSION && |
| 413 transmission_type != RTO_RETRANSMISSION) { | 413 transmission_type != RTO_RETRANSMISSION) { |
| 414 unacked_packets_.RemoveFromInFlight(packet_number); | 414 unacked_packets_.RemoveFromInFlight(packet_number); |
| 415 } | 415 } |
| 416 if (delegate_ != nullptr) { | 416 if (delegate_ != nullptr) { |
| 417 delegate_->OnRetransmissionMarked(path_id_, packet_number, | 417 delegate_->OnRetransmissionMarked(path_id_, packet_number, |
| 418 transmission_type); | 418 transmission_type); |
| 419 } else { | 419 } else { |
| 420 // TODO(ianswett): Currently the RTO can fire while there are pending NACK | 420 // TODO(ianswett): Currently the RTO can fire while there are pending NACK |
| 421 // retransmissions for the same data, which is not ideal. | 421 // retransmissions for the same data, which is not ideal. |
| 422 if (base::ContainsKey(pending_retransmissions_, packet_number)) { | 422 if (base::ContainsKey(pending_retransmissions_, packet_number)) { |
| 423 return; | 423 return; |
| 424 } | 424 } |
| 425 | 425 |
| 426 pending_retransmissions_[packet_number] = transmission_type; | 426 pending_retransmissions_[packet_number] = transmission_type; |
| 427 } | 427 } |
| 428 } | 428 } |
| 429 | 429 |
| 430 void QuicSentPacketManager::RecordOneSpuriousRetransmission( | 430 void QuicSentPacketManager::RecordOneSpuriousRetransmission( |
| 431 const TransmissionInfo& info) { | 431 const QuicTransmissionInfo& info) { |
| 432 stats_->bytes_spuriously_retransmitted += info.bytes_sent; | 432 stats_->bytes_spuriously_retransmitted += info.bytes_sent; |
| 433 ++stats_->packets_spuriously_retransmitted; | 433 ++stats_->packets_spuriously_retransmitted; |
| 434 if (debug_delegate_ != nullptr) { | 434 if (debug_delegate_ != nullptr) { |
| 435 debug_delegate_->OnSpuriousPacketRetransmission(info.transmission_type, | 435 debug_delegate_->OnSpuriousPacketRetransmission(info.transmission_type, |
| 436 info.bytes_sent); | 436 info.bytes_sent); |
| 437 } | 437 } |
| 438 } | 438 } |
| 439 | 439 |
| 440 void QuicSentPacketManager::RecordSpuriousRetransmissions( | 440 void QuicSentPacketManager::RecordSpuriousRetransmissions( |
| 441 const TransmissionInfo& info, | 441 const QuicTransmissionInfo& info, |
| 442 QuicPacketNumber acked_packet_number) { | 442 QuicPacketNumber acked_packet_number) { |
| 443 QuicPacketNumber retransmission = info.retransmission; | 443 QuicPacketNumber retransmission = info.retransmission; |
| 444 while (retransmission != 0) { | 444 while (retransmission != 0) { |
| 445 const TransmissionInfo& retransmit_info = | 445 const QuicTransmissionInfo& retransmit_info = |
| 446 unacked_packets_.GetTransmissionInfo(retransmission); | 446 unacked_packets_.GetTransmissionInfo(retransmission); |
| 447 retransmission = retransmit_info.retransmission; | 447 retransmission = retransmit_info.retransmission; |
| 448 RecordOneSpuriousRetransmission(retransmit_info); | 448 RecordOneSpuriousRetransmission(retransmit_info); |
| 449 } | 449 } |
| 450 // Only inform the loss detection of spurious retransmits it caused. | 450 // Only inform the loss detection of spurious retransmits it caused. |
| 451 if (unacked_packets_.GetTransmissionInfo(info.retransmission) | 451 if (unacked_packets_.GetTransmissionInfo(info.retransmission) |
| 452 .transmission_type == LOSS_RETRANSMISSION) { | 452 .transmission_type == LOSS_RETRANSMISSION) { |
| 453 loss_algorithm_->SpuriousRetransmitDetected( | 453 loss_algorithm_->SpuriousRetransmitDetected( |
| 454 unacked_packets_, clock_->Now(), rtt_stats_, info.retransmission); | 454 unacked_packets_, clock_->Now(), rtt_stats_, info.retransmission); |
| 455 } | 455 } |
| 456 } | 456 } |
| 457 | 457 |
| 458 bool QuicSentPacketManager::HasPendingRetransmissions() const { | 458 bool QuicSentPacketManager::HasPendingRetransmissions() const { |
| 459 return !pending_retransmissions_.empty(); | 459 return !pending_retransmissions_.empty(); |
| 460 } | 460 } |
| 461 | 461 |
| 462 PendingRetransmission QuicSentPacketManager::NextPendingRetransmission() { | 462 QuicPendingRetransmission QuicSentPacketManager::NextPendingRetransmission() { |
| 463 QUIC_BUG_IF(pending_retransmissions_.empty()) | 463 QUIC_BUG_IF(pending_retransmissions_.empty()) |
| 464 << "Unexpected call to PendingRetransmissions() with empty pending " | 464 << "Unexpected call to PendingRetransmissions() with empty pending " |
| 465 << "retransmission list. Corrupted memory usage imminent."; | 465 << "retransmission list. Corrupted memory usage imminent."; |
| 466 QuicPacketNumber packet_number = pending_retransmissions_.begin()->first; | 466 QuicPacketNumber packet_number = pending_retransmissions_.begin()->first; |
| 467 TransmissionType transmission_type = pending_retransmissions_.begin()->second; | 467 TransmissionType transmission_type = pending_retransmissions_.begin()->second; |
| 468 if (unacked_packets_.HasPendingCryptoPackets()) { | 468 if (unacked_packets_.HasPendingCryptoPackets()) { |
| 469 // Ensure crypto packets are retransmitted before other packets. | 469 // Ensure crypto packets are retransmitted before other packets. |
| 470 for (const auto& pair : pending_retransmissions_) { | 470 for (const auto& pair : pending_retransmissions_) { |
| 471 if (HasCryptoHandshake( | 471 if (HasCryptoHandshake( |
| 472 unacked_packets_.GetTransmissionInfo(pair.first))) { | 472 unacked_packets_.GetTransmissionInfo(pair.first))) { |
| 473 packet_number = pair.first; | 473 packet_number = pair.first; |
| 474 transmission_type = pair.second; | 474 transmission_type = pair.second; |
| 475 break; | 475 break; |
| 476 } | 476 } |
| 477 } | 477 } |
| 478 } | 478 } |
| 479 DCHECK(unacked_packets_.IsUnacked(packet_number)) << packet_number; | 479 DCHECK(unacked_packets_.IsUnacked(packet_number)) << packet_number; |
| 480 const TransmissionInfo& transmission_info = | 480 const QuicTransmissionInfo& transmission_info = |
| 481 unacked_packets_.GetTransmissionInfo(packet_number); | 481 unacked_packets_.GetTransmissionInfo(packet_number); |
| 482 DCHECK(!transmission_info.retransmittable_frames.empty()); | 482 DCHECK(!transmission_info.retransmittable_frames.empty()); |
| 483 | 483 |
| 484 return PendingRetransmission(path_id_, packet_number, transmission_type, | 484 return QuicPendingRetransmission(path_id_, packet_number, transmission_type, |
| 485 transmission_info.retransmittable_frames, | 485 transmission_info.retransmittable_frames, |
| 486 transmission_info.has_crypto_handshake, | 486 transmission_info.has_crypto_handshake, |
| 487 transmission_info.num_padding_bytes, | 487 transmission_info.num_padding_bytes, |
| 488 transmission_info.encryption_level, | 488 transmission_info.encryption_level, |
| 489 transmission_info.packet_number_length); | 489 transmission_info.packet_number_length); |
| 490 } | 490 } |
| 491 | 491 |
| 492 QuicPacketNumber QuicSentPacketManager::GetNewestRetransmission( | 492 QuicPacketNumber QuicSentPacketManager::GetNewestRetransmission( |
| 493 QuicPacketNumber packet_number, | 493 QuicPacketNumber packet_number, |
| 494 const TransmissionInfo& transmission_info) const { | 494 const QuicTransmissionInfo& transmission_info) const { |
| 495 QuicPacketNumber retransmission = transmission_info.retransmission; | 495 QuicPacketNumber retransmission = transmission_info.retransmission; |
| 496 while (retransmission != 0) { | 496 while (retransmission != 0) { |
| 497 packet_number = retransmission; | 497 packet_number = retransmission; |
| 498 retransmission = | 498 retransmission = |
| 499 unacked_packets_.GetTransmissionInfo(retransmission).retransmission; | 499 unacked_packets_.GetTransmissionInfo(retransmission).retransmission; |
| 500 } | 500 } |
| 501 return packet_number; | 501 return packet_number; |
| 502 } | 502 } |
| 503 | 503 |
| 504 void QuicSentPacketManager::MarkPacketNotRetransmittable( | 504 void QuicSentPacketManager::MarkPacketNotRetransmittable( |
| 505 QuicPacketNumber packet_number, | 505 QuicPacketNumber packet_number, |
| 506 QuicTime::Delta ack_delay_time) { | 506 QuicTime::Delta ack_delay_time) { |
| 507 if (!unacked_packets_.IsUnacked(packet_number)) { | 507 if (!unacked_packets_.IsUnacked(packet_number)) { |
| 508 return; | 508 return; |
| 509 } | 509 } |
| 510 | 510 |
| 511 const TransmissionInfo& transmission_info = | 511 const QuicTransmissionInfo& transmission_info = |
| 512 unacked_packets_.GetTransmissionInfo(packet_number); | 512 unacked_packets_.GetTransmissionInfo(packet_number); |
| 513 QuicPacketNumber newest_transmission = | 513 QuicPacketNumber newest_transmission = |
| 514 GetNewestRetransmission(packet_number, transmission_info); | 514 GetNewestRetransmission(packet_number, transmission_info); |
| 515 // We do not need to retransmit this packet anymore. | 515 // We do not need to retransmit this packet anymore. |
| 516 if (delegate_ != nullptr) { | 516 if (delegate_ != nullptr) { |
| 517 delegate_->OnPacketMarkedNotRetransmittable(path_id_, newest_transmission, | 517 delegate_->OnPacketMarkedNotRetransmittable(path_id_, newest_transmission, |
| 518 ack_delay_time); | 518 ack_delay_time); |
| 519 } else { | 519 } else { |
| 520 pending_retransmissions_.erase(newest_transmission); | 520 pending_retransmissions_.erase(newest_transmission); |
| 521 } | 521 } |
| 522 | 522 |
| 523 unacked_packets_.NotifyAndClearListeners(newest_transmission, ack_delay_time); | 523 unacked_packets_.NotifyAndClearListeners(newest_transmission, ack_delay_time); |
| 524 unacked_packets_.RemoveRetransmittability(packet_number); | 524 unacked_packets_.RemoveRetransmittability(packet_number); |
| 525 } | 525 } |
| 526 | 526 |
| 527 void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number, | 527 void QuicSentPacketManager::MarkPacketHandled(QuicPacketNumber packet_number, |
| 528 TransmissionInfo* info, | 528 QuicTransmissionInfo* info, |
| 529 QuicTime::Delta ack_delay_time) { | 529 QuicTime::Delta ack_delay_time) { |
| 530 QuicPacketNumber newest_transmission = | 530 QuicPacketNumber newest_transmission = |
| 531 GetNewestRetransmission(packet_number, *info); | 531 GetNewestRetransmission(packet_number, *info); |
| 532 // Remove the most recent packet, if it is pending retransmission. | 532 // Remove the most recent packet, if it is pending retransmission. |
| 533 if (delegate_ != nullptr) { | 533 if (delegate_ != nullptr) { |
| 534 delegate_->OnPacketMarkedHandled(path_id_, newest_transmission, | 534 delegate_->OnPacketMarkedHandled(path_id_, newest_transmission, |
| 535 ack_delay_time); | 535 ack_delay_time); |
| 536 } else { | 536 } else { |
| 537 pending_retransmissions_.erase(newest_transmission); | 537 pending_retransmissions_.erase(newest_transmission); |
| 538 } | 538 } |
| 539 | 539 |
| 540 // The AckListener needs to be notified about the most recent | 540 // The AckListener needs to be notified about the most recent |
| 541 // transmission, since that's the one only one it tracks. | 541 // transmission, since that's the one only one it tracks. |
| 542 if (newest_transmission == packet_number) { | 542 if (newest_transmission == packet_number) { |
| 543 unacked_packets_.NotifyAndClearListeners(&info->ack_listeners, | 543 unacked_packets_.NotifyAndClearListeners(&info->ack_listeners, |
| 544 ack_delay_time); | 544 ack_delay_time); |
| 545 } else { | 545 } else { |
| 546 unacked_packets_.NotifyAndClearListeners(newest_transmission, | 546 unacked_packets_.NotifyAndClearListeners(newest_transmission, |
| 547 ack_delay_time); | 547 ack_delay_time); |
| 548 RecordSpuriousRetransmissions(*info, packet_number); | 548 RecordSpuriousRetransmissions(*info, packet_number); |
| 549 // Remove the most recent packet from flight if it's a crypto handshake | 549 // Remove the most recent packet from flight if it's a crypto handshake |
| 550 // packet, since they won't be acked now that one has been processed. | 550 // packet, since they won't be acked now that one has been processed. |
| 551 // Other crypto handshake packets won't be in flight, only the newest | 551 // Other crypto handshake packets won't be in flight, only the newest |
| 552 // transmission of a crypto packet is in flight at once. | 552 // transmission of a crypto packet is in flight at once. |
| 553 // TODO(ianswett): Instead of handling all crypto packets special, | 553 // TODO(ianswett): Instead of handling all crypto packets special, |
| 554 // only handle nullptr encrypted packets in a special way. | 554 // only handle nullptr encrypted packets in a special way. |
| 555 const TransmissionInfo& newest_transmission_info = | 555 const QuicTransmissionInfo& newest_transmission_info = |
| 556 unacked_packets_.GetTransmissionInfo(newest_transmission); | 556 unacked_packets_.GetTransmissionInfo(newest_transmission); |
| 557 if (HasCryptoHandshake(newest_transmission_info)) { | 557 if (HasCryptoHandshake(newest_transmission_info)) { |
| 558 unacked_packets_.RemoveFromInFlight(newest_transmission); | 558 unacked_packets_.RemoveFromInFlight(newest_transmission); |
| 559 } | 559 } |
| 560 } | 560 } |
| 561 | 561 |
| 562 if (network_change_visitor_ != nullptr && | 562 if (network_change_visitor_ != nullptr && |
| 563 info->bytes_sent > largest_mtu_acked_) { | 563 info->bytes_sent > largest_mtu_acked_) { |
| 564 largest_mtu_acked_ = info->bytes_sent; | 564 largest_mtu_acked_ = info->bytes_sent; |
| 565 network_change_visitor_->OnPathMtuIncreased(largest_mtu_acked_); | 565 network_change_visitor_->OnPathMtuIncreased(largest_mtu_acked_); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 QuicTime ack_receive_time) { | 776 QuicTime ack_receive_time) { |
| 777 // We rely on ack_delay_time to compute an RTT estimate, so we | 777 // We rely on ack_delay_time to compute an RTT estimate, so we |
| 778 // only update rtt when the largest observed gets acked. | 778 // only update rtt when the largest observed gets acked. |
| 779 // NOTE: If ack is a truncated ack, then the largest observed is in fact | 779 // NOTE: If ack is a truncated ack, then the largest observed is in fact |
| 780 // unacked, and may cause an RTT sample to be taken. | 780 // unacked, and may cause an RTT sample to be taken. |
| 781 if (!unacked_packets_.IsUnacked(ack_frame.largest_observed)) { | 781 if (!unacked_packets_.IsUnacked(ack_frame.largest_observed)) { |
| 782 return false; | 782 return false; |
| 783 } | 783 } |
| 784 // We calculate the RTT based on the highest ACKed packet number, the lower | 784 // We calculate the RTT based on the highest ACKed packet number, the lower |
| 785 // packet numbers will include the ACK aggregation delay. | 785 // packet numbers will include the ACK aggregation delay. |
| 786 const TransmissionInfo& transmission_info = | 786 const QuicTransmissionInfo& transmission_info = |
| 787 unacked_packets_.GetTransmissionInfo(ack_frame.largest_observed); | 787 unacked_packets_.GetTransmissionInfo(ack_frame.largest_observed); |
| 788 // Ensure the packet has a valid sent time. | 788 // Ensure the packet has a valid sent time. |
| 789 if (transmission_info.sent_time == QuicTime::Zero()) { | 789 if (transmission_info.sent_time == QuicTime::Zero()) { |
| 790 QUIC_BUG << "Acked packet has zero sent time, largest_observed:" | 790 QUIC_BUG << "Acked packet has zero sent time, largest_observed:" |
| 791 << ack_frame.largest_observed; | 791 << ack_frame.largest_observed; |
| 792 return false; | 792 return false; |
| 793 } | 793 } |
| 794 | 794 |
| 795 QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time; | 795 QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time; |
| 796 const int kMaxSendDeltaSeconds = 30; | 796 const int kMaxSendDeltaSeconds = 30; |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1042 } | 1042 } |
| 1043 | 1043 |
| 1044 size_t QuicSentPacketManager::GetConsecutiveRtoCount() const { | 1044 size_t QuicSentPacketManager::GetConsecutiveRtoCount() const { |
| 1045 return consecutive_rto_count_; | 1045 return consecutive_rto_count_; |
| 1046 } | 1046 } |
| 1047 | 1047 |
| 1048 size_t QuicSentPacketManager::GetConsecutiveTlpCount() const { | 1048 size_t QuicSentPacketManager::GetConsecutiveTlpCount() const { |
| 1049 return consecutive_tlp_count_; | 1049 return consecutive_tlp_count_; |
| 1050 } | 1050 } |
| 1051 | 1051 |
| 1052 TransmissionInfo* QuicSentPacketManager::GetMutableTransmissionInfo( | 1052 QuicTransmissionInfo* QuicSentPacketManager::GetMutableTransmissionInfo( |
| 1053 QuicPacketNumber packet_number) { | 1053 QuicPacketNumber packet_number) { |
| 1054 return unacked_packets_.GetMutableTransmissionInfo(packet_number); | 1054 return unacked_packets_.GetMutableTransmissionInfo(packet_number); |
| 1055 } | 1055 } |
| 1056 | 1056 |
| 1057 void QuicSentPacketManager::RemoveObsoletePackets() { | 1057 void QuicSentPacketManager::RemoveObsoletePackets() { |
| 1058 unacked_packets_.RemoveObsoletePackets(); | 1058 unacked_packets_.RemoveObsoletePackets(); |
| 1059 } | 1059 } |
| 1060 | 1060 |
| 1061 void QuicSentPacketManager::OnApplicationLimited() { | 1061 void QuicSentPacketManager::OnApplicationLimited() { |
| 1062 send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight()); | 1062 send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight()); |
| 1063 } | 1063 } |
| 1064 | 1064 |
| 1065 } // namespace net | 1065 } // namespace net |
| OLD | NEW |