| 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 |