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 |