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 |