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 "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "net/quic/congestion_control/pacing_sender.h" | 9 #include "net/quic/congestion_control/pacing_sender.h" |
10 #include "net/quic/crypto/crypto_protocol.h" | 10 #include "net/quic/crypto/crypto_protocol.h" |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 const TransmissionInfo& transmission_info) { | 361 const TransmissionInfo& transmission_info) { |
362 if (transmission_info.retransmittable_frames == NULL) { | 362 if (transmission_info.retransmittable_frames == NULL) { |
363 return false; | 363 return false; |
364 } | 364 } |
365 return transmission_info.retransmittable_frames->HasCryptoHandshake() == | 365 return transmission_info.retransmittable_frames->HasCryptoHandshake() == |
366 IS_HANDSHAKE; | 366 IS_HANDSHAKE; |
367 } | 367 } |
368 | 368 |
369 QuicSentPacketManager::UnackedPacketMap::iterator | 369 QuicSentPacketManager::UnackedPacketMap::iterator |
370 QuicSentPacketManager::MarkPacketHandled( | 370 QuicSentPacketManager::MarkPacketHandled( |
371 QuicPacketSequenceNumber sequence_number, ReceivedByPeer received_by_peer) { | 371 QuicPacketSequenceNumber sequence_number, |
372 DCHECK(ContainsKey(unacked_packets_, sequence_number)); | 372 ReceivedByPeer received_by_peer) { |
373 | 373 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); |
| 374 if (it == unacked_packets_.end()) { |
| 375 LOG(DFATAL) << "Packet is not unacked: " << sequence_number; |
| 376 return it; |
| 377 } |
374 // If this packet is pending, remove it and inform the send algorithm. | 378 // If this packet is pending, remove it and inform the send algorithm. |
375 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); | |
376 if (it->second.pending) { | 379 if (it->second.pending) { |
377 size_t bytes_sent = packet_history_map_[sequence_number]->bytes_sent(); | 380 size_t bytes_sent = packet_history_map_[sequence_number]->bytes_sent(); |
378 if (received_by_peer == RECEIVED_BY_PEER) { | 381 if (received_by_peer == RECEIVED_BY_PEER) { |
379 send_algorithm_->OnPacketAcked(sequence_number, bytes_sent); | 382 send_algorithm_->OnPacketAcked(sequence_number, bytes_sent); |
380 } else { | 383 } else { |
381 // It's been abandoned. | 384 // It's been abandoned. |
382 send_algorithm_->OnPacketAbandoned(sequence_number, bytes_sent); | 385 send_algorithm_->OnPacketAbandoned(sequence_number, bytes_sent); |
383 } | 386 } |
384 it->second.pending = false; | 387 it->second.pending = false; |
385 } | 388 } |
386 | 389 |
387 // If this packet has never been retransmitted, then simply drop it. | 390 SequenceNumberSet* previous_transmissions = it->second.previous_transmissions; |
388 if (it->second.previous_transmissions == NULL) { | 391 if (previous_transmissions == NULL) { |
389 ++it; | 392 previous_transmissions = new SequenceNumberSet; |
390 DiscardPacket(sequence_number); | 393 previous_transmissions->insert(sequence_number); |
391 return it; | |
392 } | 394 } |
393 | |
394 SequenceNumberSet* previous_transmissions = it->second.previous_transmissions; | |
395 DCHECK(!previous_transmissions->empty()); | 395 DCHECK(!previous_transmissions->empty()); |
396 SequenceNumberSet::reverse_iterator previous_transmissions_it = | 396 SequenceNumberSet::reverse_iterator previous_transmissions_it = |
397 previous_transmissions->rbegin(); | 397 previous_transmissions->rbegin(); |
398 QuicPacketSequenceNumber newest_transmission = *previous_transmissions_it; | 398 QuicPacketSequenceNumber newest_transmission = *previous_transmissions_it; |
399 TransmissionInfo* transmission_info = | |
400 FindOrNull(unacked_packets_, newest_transmission); | |
401 if (newest_transmission != sequence_number) { | 399 if (newest_transmission != sequence_number) { |
402 ++stats_->packets_spuriously_retransmitted; | 400 ++stats_->packets_spuriously_retransmitted; |
403 } | 401 } |
404 if (newest_transmission == sequence_number) { | 402 |
405 DiscardPacket(newest_transmission); | 403 bool has_cryto_handshake = HasCryptoHandshake( |
406 } else if (HasCryptoHandshake(*transmission_info)) { | 404 *FindOrNull(unacked_packets_, newest_transmission)); |
407 // If it's a crypto handshake packet, discard it and all retransmissions, | 405 if (has_cryto_handshake) { |
408 // since they won't be acked now that one has been processed. | 406 --pending_crypto_packet_count_; |
409 if (transmission_info->pending) { | |
410 OnPacketAbandoned(unacked_packets_.find(newest_transmission)); | |
411 } | |
412 DiscardPacket(newest_transmission); | |
413 } else { | |
414 // If we have received an ack for a previous transmission of a packet, | |
415 // we want to keep the "new" transmission of the packet unacked, | |
416 // but prevent the data from being retransmitted. | |
417 delete transmission_info->retransmittable_frames; | |
418 transmission_info->retransmittable_frames = NULL; | |
419 transmission_info->previous_transmissions = NULL; | |
420 } | 407 } |
421 | |
422 // Clear out information all previous transmissions unless they're pending. | |
423 ++previous_transmissions_it; | |
424 while (previous_transmissions_it != previous_transmissions->rend()) { | 408 while (previous_transmissions_it != previous_transmissions->rend()) { |
425 QuicPacketSequenceNumber previous_transmission = *previous_transmissions_it; | 409 QuicPacketSequenceNumber previous_transmission = *previous_transmissions_it; |
| 410 TransmissionInfo* transmission_info = |
| 411 FindOrNull(unacked_packets_, previous_transmission); |
| 412 if (transmission_info->retransmittable_frames != NULL) { |
| 413 // Since some version of this packet has been acked, ensure that |
| 414 // the data is not retransmitted again. |
| 415 delete transmission_info->retransmittable_frames; |
| 416 transmission_info->retransmittable_frames = NULL; |
| 417 } |
| 418 if (ContainsKey(pending_retransmissions_, previous_transmission)) { |
| 419 // Don't bother retransmitting this packet, if it has been |
| 420 // marked for retransmission. |
| 421 pending_retransmissions_.erase(previous_transmission); |
| 422 } |
| 423 if (has_cryto_handshake) { |
| 424 // If it's a crypto handshake packet, discard it and all retransmissions, |
| 425 // since they won't be acked now that one has been processed. |
| 426 if (transmission_info->pending) { |
| 427 OnPacketAbandoned(unacked_packets_.find(newest_transmission)); |
| 428 } |
| 429 transmission_info->pending = false; |
| 430 } |
| 431 if (!transmission_info->pending) { |
| 432 unacked_packets_.erase(previous_transmission); |
| 433 } else { |
| 434 transmission_info->previous_transmissions = NULL; |
| 435 } |
426 ++previous_transmissions_it; | 436 ++previous_transmissions_it; |
427 // If the packet was TLP retransmitted, the old copy is still pending. | |
428 // Keep it until it is lost or acked. | |
429 if (unacked_packets_[previous_transmission].pending) { | |
430 // Previous transmissions will be deleted, so set it to NULL. | |
431 unacked_packets_[previous_transmission].previous_transmissions = NULL; | |
432 } else { | |
433 DiscardPacket(previous_transmission); | |
434 } | |
435 } | 437 } |
436 | |
437 delete previous_transmissions; | 438 delete previous_transmissions; |
438 | 439 |
439 if (ContainsKey(pending_retransmissions_, newest_transmission)) { | |
440 pending_retransmissions_.erase(newest_transmission); | |
441 if (!unacked_packets_[newest_transmission].pending) { | |
442 // If the newest transmission has already been marked for retransmission | |
443 // and has already been abandoned, then we should remove it from | |
444 // unacked_packets_, as well as cancel the retransmission. | |
445 DCHECK(ContainsKey(unacked_packets_, newest_transmission)); | |
446 DCHECK(!unacked_packets_[newest_transmission].previous_transmissions); | |
447 unacked_packets_.erase(newest_transmission); | |
448 } | |
449 } | |
450 | |
451 UnackedPacketMap::iterator next_unacked = unacked_packets_.begin(); | 440 UnackedPacketMap::iterator next_unacked = unacked_packets_.begin(); |
452 while (next_unacked != unacked_packets_.end() && | 441 while (next_unacked != unacked_packets_.end() && |
453 next_unacked->first < sequence_number) { | 442 next_unacked->first < sequence_number) { |
454 ++next_unacked; | 443 ++next_unacked; |
455 } | 444 } |
456 return next_unacked; | 445 return next_unacked; |
457 } | 446 } |
458 | 447 |
459 void QuicSentPacketManager::DiscardPacket( | |
460 QuicPacketSequenceNumber sequence_number) { | |
461 UnackedPacketMap::iterator unacked_it = | |
462 unacked_packets_.find(sequence_number); | |
463 DCHECK(unacked_it != unacked_packets_.end()); | |
464 // Ensure the packet is no longer pending when it's discarded. | |
465 DCHECK(!unacked_it->second.pending); | |
466 | |
467 RetransmittableFrames* retransmittable_frames = | |
468 unacked_it->second.retransmittable_frames; | |
469 if (HasCryptoHandshake(unacked_it->second)) { | |
470 --pending_crypto_packet_count_; | |
471 } | |
472 | |
473 // Delete the retransmittable frames. | |
474 delete retransmittable_frames; | |
475 unacked_packets_.erase(unacked_it); | |
476 pending_retransmissions_.erase(sequence_number); | |
477 return; | |
478 } | |
479 | |
480 bool QuicSentPacketManager::IsUnacked( | 448 bool QuicSentPacketManager::IsUnacked( |
481 QuicPacketSequenceNumber sequence_number) const { | 449 QuicPacketSequenceNumber sequence_number) const { |
482 return ContainsKey(unacked_packets_, sequence_number); | 450 return ContainsKey(unacked_packets_, sequence_number); |
483 } | 451 } |
484 | 452 |
485 bool QuicSentPacketManager::HasUnackedPackets() const { | 453 bool QuicSentPacketManager::HasUnackedPackets() const { |
486 return !unacked_packets_.empty(); | 454 return !unacked_packets_.empty(); |
487 } | 455 } |
488 | 456 |
489 bool QuicSentPacketManager::HasPendingPackets() const { | 457 bool QuicSentPacketManager::HasPendingPackets() const { |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
970 } | 938 } |
971 previous_transmissions->erase(sequence_number); | 939 previous_transmissions->erase(sequence_number); |
972 if (previous_transmissions->size() == 1) { | 940 if (previous_transmissions->size() == 1) { |
973 QuicPacketSequenceNumber current = *previous_transmissions->begin(); | 941 QuicPacketSequenceNumber current = *previous_transmissions->begin(); |
974 unacked_packets_[current].previous_transmissions = NULL; | 942 unacked_packets_[current].previous_transmissions = NULL; |
975 delete previous_transmissions; | 943 delete previous_transmissions; |
976 } | 944 } |
977 } | 945 } |
978 | 946 |
979 } // namespace net | 947 } // namespace net |
OLD | NEW |