| 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 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 // TODO(ianswett): Currently the RTO can fire while there are pending NACK | 351 // TODO(ianswett): Currently the RTO can fire while there are pending NACK |
| 352 // retransmissions for the same data, which is not ideal. | 352 // retransmissions for the same data, which is not ideal. |
| 353 if (ContainsKey(pending_retransmissions_, sequence_number)) { | 353 if (ContainsKey(pending_retransmissions_, sequence_number)) { |
| 354 return; | 354 return; |
| 355 } | 355 } |
| 356 | 356 |
| 357 pending_retransmissions_[sequence_number] = transmission_type; | 357 pending_retransmissions_[sequence_number] = transmission_type; |
| 358 } | 358 } |
| 359 | 359 |
| 360 void QuicSentPacketManager::RecordSpuriousRetransmissions( | 360 void QuicSentPacketManager::RecordSpuriousRetransmissions( |
| 361 const SequenceNumberSet& all_transmissions, | 361 const SequenceNumberList& all_transmissions, |
| 362 QuicPacketSequenceNumber acked_sequence_number) { | 362 QuicPacketSequenceNumber acked_sequence_number) { |
| 363 if (acked_sequence_number < first_rto_transmission_) { | 363 if (acked_sequence_number < first_rto_transmission_) { |
| 364 // Cancel all pending RTO transmissions and restore their in flight status. | 364 // Cancel all pending RTO transmissions and restore their in flight status. |
| 365 // Replace SRTT with latest_rtt and increase the variance to prevent | 365 // Replace SRTT with latest_rtt and increase the variance to prevent |
| 366 // a spurious RTO from happening again. | 366 // a spurious RTO from happening again. |
| 367 rtt_stats_.ExpireSmoothedMetrics(); | 367 rtt_stats_.ExpireSmoothedMetrics(); |
| 368 for (PendingRetransmissionMap::const_iterator it = | 368 for (PendingRetransmissionMap::const_iterator it = |
| 369 pending_retransmissions_.begin(); | 369 pending_retransmissions_.begin(); |
| 370 it != pending_retransmissions_.end(); ++it) { | 370 it != pending_retransmissions_.end(); ++it) { |
| 371 DCHECK_EQ(it->second, RTO_RETRANSMISSION); | 371 DCHECK_EQ(it->second, RTO_RETRANSMISSION); |
| 372 unacked_packets_.RestoreInFlight(it->first); | 372 unacked_packets_.RestoreInFlight(it->first); |
| 373 } | 373 } |
| 374 pending_retransmissions_.clear(); | 374 pending_retransmissions_.clear(); |
| 375 send_algorithm_->RevertRetransmissionTimeout(); | 375 send_algorithm_->RevertRetransmissionTimeout(); |
| 376 first_rto_transmission_ = 0; | 376 first_rto_transmission_ = 0; |
| 377 ++stats_->spurious_rto_count; | 377 ++stats_->spurious_rto_count; |
| 378 } | 378 } |
| 379 for (SequenceNumberSet::const_iterator | 379 for (SequenceNumberList::const_reverse_iterator it = |
| 380 it = all_transmissions.upper_bound(acked_sequence_number), | 380 all_transmissions.rbegin(); |
| 381 end = all_transmissions.end(); | 381 it != all_transmissions.rend() && *it > acked_sequence_number; ++it) { |
| 382 it != end; | |
| 383 ++it) { | |
| 384 const TransmissionInfo& retransmit_info = | 382 const TransmissionInfo& retransmit_info = |
| 385 unacked_packets_.GetTransmissionInfo(*it); | 383 unacked_packets_.GetTransmissionInfo(*it); |
| 386 | 384 |
| 387 stats_->bytes_spuriously_retransmitted += retransmit_info.bytes_sent; | 385 stats_->bytes_spuriously_retransmitted += retransmit_info.bytes_sent; |
| 388 ++stats_->packets_spuriously_retransmitted; | 386 ++stats_->packets_spuriously_retransmitted; |
| 389 if (debug_delegate_ != NULL) { | 387 if (debug_delegate_ != NULL) { |
| 390 debug_delegate_->OnSpuriousPacketRetransmition( | 388 debug_delegate_->OnSpuriousPacketRetransmition( |
| 391 retransmit_info.transmission_type, | 389 retransmit_info.transmission_type, |
| 392 retransmit_info.bytes_sent); | 390 retransmit_info.bytes_sent); |
| 393 } | 391 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 void QuicSentPacketManager::MarkPacketRevived( | 429 void QuicSentPacketManager::MarkPacketRevived( |
| 432 QuicPacketSequenceNumber sequence_number, | 430 QuicPacketSequenceNumber sequence_number, |
| 433 QuicTime::Delta delta_largest_observed) { | 431 QuicTime::Delta delta_largest_observed) { |
| 434 if (!unacked_packets_.IsUnacked(sequence_number)) { | 432 if (!unacked_packets_.IsUnacked(sequence_number)) { |
| 435 return; | 433 return; |
| 436 } | 434 } |
| 437 | 435 |
| 438 const TransmissionInfo& transmission_info = | 436 const TransmissionInfo& transmission_info = |
| 439 unacked_packets_.GetTransmissionInfo(sequence_number); | 437 unacked_packets_.GetTransmissionInfo(sequence_number); |
| 440 QuicPacketSequenceNumber newest_transmission = | 438 QuicPacketSequenceNumber newest_transmission = |
| 441 *transmission_info.all_transmissions->rbegin(); | 439 transmission_info.all_transmissions == NULL ? |
| 440 sequence_number : *transmission_info.all_transmissions->rbegin(); |
| 442 // This packet has been revived at the receiver. If we were going to | 441 // This packet has been revived at the receiver. If we were going to |
| 443 // retransmit it, do not retransmit it anymore. | 442 // retransmit it, do not retransmit it anymore. |
| 444 pending_retransmissions_.erase(newest_transmission); | 443 pending_retransmissions_.erase(newest_transmission); |
| 445 | 444 |
| 446 // The AckNotifierManager needs to be notified for revived packets, | 445 // The AckNotifierManager needs to be notified for revived packets, |
| 447 // since it indicates the packet arrived from the appliction's perspective. | 446 // since it indicates the packet arrived from the appliction's perspective. |
| 448 if (transmission_info.retransmittable_frames) { | 447 if (transmission_info.retransmittable_frames) { |
| 449 ack_notifier_manager_.OnPacketAcked( | 448 ack_notifier_manager_.OnPacketAcked( |
| 450 newest_transmission, delta_largest_observed); | 449 newest_transmission, delta_largest_observed); |
| 451 } | 450 } |
| 452 | 451 |
| 453 unacked_packets_.RemoveRetransmittability(sequence_number); | 452 unacked_packets_.RemoveRetransmittability(sequence_number); |
| 454 } | 453 } |
| 455 | 454 |
| 456 void QuicSentPacketManager::MarkPacketHandled( | 455 void QuicSentPacketManager::MarkPacketHandled( |
| 457 QuicPacketSequenceNumber sequence_number, | 456 QuicPacketSequenceNumber sequence_number, |
| 458 const TransmissionInfo& info, | 457 const TransmissionInfo& info, |
| 459 QuicTime::Delta delta_largest_observed) { | 458 QuicTime::Delta delta_largest_observed) { |
| 460 QuicPacketSequenceNumber newest_transmission = | 459 QuicPacketSequenceNumber newest_transmission = |
| 461 *info.all_transmissions->rbegin(); | 460 info.all_transmissions == NULL ? |
| 461 sequence_number : *info.all_transmissions->rbegin(); |
| 462 // Remove the most recent packet, if it is pending retransmission. | 462 // Remove the most recent packet, if it is pending retransmission. |
| 463 pending_retransmissions_.erase(newest_transmission); | 463 pending_retransmissions_.erase(newest_transmission); |
| 464 | 464 |
| 465 // Notify observers about the ACKed packet. | 465 // The AckNotifierManager needs to be notified about the most recent |
| 466 { | 466 // transmission, since that's the one only one it tracks. |
| 467 // The AckNotifierManager needs to be notified about the most recent | 467 ack_notifier_manager_.OnPacketAcked(newest_transmission, |
| 468 // transmission, since that's the one only one it tracks. | 468 delta_largest_observed); |
| 469 ack_notifier_manager_.OnPacketAcked(newest_transmission, | 469 if (newest_transmission != sequence_number) { |
| 470 delta_largest_observed); | 470 RecordSpuriousRetransmissions(*info.all_transmissions, sequence_number); |
| 471 if (newest_transmission != sequence_number) { | 471 // Remove the most recent packet from flight if it's a crypto handshake |
| 472 RecordSpuriousRetransmissions(*info.all_transmissions, sequence_number); | 472 // packet, since they won't be acked now that one has been processed. |
| 473 // Other crypto handshake packets won't be in flight, only the newest |
| 474 // transmission of a crypto packet is in flight at once. |
| 475 // TODO(ianswett): Instead of handling all crypto packets special, |
| 476 // only handle NULL encrypted packets in a special way. |
| 477 if (HasCryptoHandshake( |
| 478 unacked_packets_.GetTransmissionInfo(newest_transmission))) { |
| 479 unacked_packets_.RemoveFromInFlight(newest_transmission); |
| 473 } | 480 } |
| 474 } | 481 } |
| 475 | 482 |
| 476 // Two cases for MarkPacketHandled: | |
| 477 // 1) Handle the most recent or a crypto packet, so remove all transmissions. | |
| 478 // 2) Handle old transmission, keep all other pending transmissions, | |
| 479 // but disassociate them from one another. | |
| 480 | |
| 481 // If it's a crypto handshake packet, discard it and all retransmissions, | |
| 482 // since they won't be acked now that one has been processed. | |
| 483 // TODO(ianswett): Instead of handling all crypto packets in a special way, | |
| 484 // only handle NULL encrypted packets in a special way. | |
| 485 if (HasCryptoHandshake( | |
| 486 unacked_packets_.GetTransmissionInfo(newest_transmission))) { | |
| 487 unacked_packets_.RemoveFromInFlight(newest_transmission); | |
| 488 } | |
| 489 unacked_packets_.RemoveFromInFlight(sequence_number); | 483 unacked_packets_.RemoveFromInFlight(sequence_number); |
| 490 unacked_packets_.RemoveRetransmittability(sequence_number); | 484 unacked_packets_.RemoveRetransmittability(sequence_number); |
| 491 } | 485 } |
| 492 | 486 |
| 493 bool QuicSentPacketManager::IsUnacked( | 487 bool QuicSentPacketManager::IsUnacked( |
| 494 QuicPacketSequenceNumber sequence_number) const { | 488 QuicPacketSequenceNumber sequence_number) const { |
| 495 return unacked_packets_.IsUnacked(sequence_number); | 489 return unacked_packets_.IsUnacked(sequence_number); |
| 496 } | 490 } |
| 497 | 491 |
| 498 bool QuicSentPacketManager::HasUnackedPackets() const { | 492 bool QuicSentPacketManager::HasUnackedPackets() const { |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 875 | 869 |
| 876 // Set up a pacing sender with a 5 millisecond alarm granularity. | 870 // Set up a pacing sender with a 5 millisecond alarm granularity. |
| 877 using_pacing_ = true; | 871 using_pacing_ = true; |
| 878 send_algorithm_.reset( | 872 send_algorithm_.reset( |
| 879 new PacingSender(send_algorithm_.release(), | 873 new PacingSender(send_algorithm_.release(), |
| 880 QuicTime::Delta::FromMilliseconds(5), | 874 QuicTime::Delta::FromMilliseconds(5), |
| 881 kInitialUnpacedBurst)); | 875 kInitialUnpacedBurst)); |
| 882 } | 876 } |
| 883 | 877 |
| 884 } // namespace net | 878 } // namespace net |
| OLD | NEW |