| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_packet_creator.h" | 5 #include "net/quic/quic_packet_creator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "net/quic/crypto/quic_random.h" | 11 #include "net/quic/crypto/quic_random.h" |
| 12 #include "net/quic/quic_bug_tracker.h" |
| 12 #include "net/quic/quic_data_writer.h" | 13 #include "net/quic/quic_data_writer.h" |
| 13 #include "net/quic/quic_fec_group.h" | 14 #include "net/quic/quic_fec_group.h" |
| 14 #include "net/quic/quic_flags.h" | 15 #include "net/quic/quic_flags.h" |
| 15 #include "net/quic/quic_utils.h" | 16 #include "net/quic/quic_utils.h" |
| 16 | 17 |
| 17 using base::StringPiece; | 18 using base::StringPiece; |
| 18 using std::make_pair; | 19 using std::make_pair; |
| 19 using std::max; | 20 using std::max; |
| 20 using std::min; | 21 using std::min; |
| 21 using std::pair; | 22 using std::pair; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 } | 169 } |
| 169 fec_group_.reset(nullptr); | 170 fec_group_.reset(nullptr); |
| 170 } | 171 } |
| 171 | 172 |
| 172 bool QuicPacketCreator::IsFecGroupOpen() const { | 173 bool QuicPacketCreator::IsFecGroupOpen() const { |
| 173 return fec_group_.get() != nullptr; | 174 return fec_group_.get() != nullptr; |
| 174 } | 175 } |
| 175 | 176 |
| 176 void QuicPacketCreator::StartFecProtectingPackets() { | 177 void QuicPacketCreator::StartFecProtectingPackets() { |
| 177 if (max_packets_per_fec_group_ == 0) { | 178 if (max_packets_per_fec_group_ == 0) { |
| 178 LOG(DFATAL) << "Cannot start FEC protection when FEC is not enabled."; | 179 QUIC_BUG << "Cannot start FEC protection when FEC is not enabled."; |
| 179 return; | 180 return; |
| 180 } | 181 } |
| 181 // TODO(jri): This currently requires that the generator flush out any | 182 // TODO(jri): This currently requires that the generator flush out any |
| 182 // pending frames when FEC protection is turned on. If current packet can be | 183 // pending frames when FEC protection is turned on. If current packet can be |
| 183 // converted to an FEC protected packet, do it. This will require the | 184 // converted to an FEC protected packet, do it. This will require the |
| 184 // generator to check if the resulting expansion still allows the incoming | 185 // generator to check if the resulting expansion still allows the incoming |
| 185 // frame to be added to the packet. | 186 // frame to be added to the packet. |
| 186 if (HasPendingFrames()) { | 187 if (HasPendingFrames()) { |
| 187 LOG(DFATAL) << "Cannot start FEC protection with pending frames."; | 188 QUIC_BUG << "Cannot start FEC protection with pending frames."; |
| 188 return; | 189 return; |
| 189 } | 190 } |
| 190 DCHECK(!fec_protect_); | 191 DCHECK(!fec_protect_); |
| 191 fec_protect_ = true; | 192 fec_protect_ = true; |
| 192 } | 193 } |
| 193 | 194 |
| 194 void QuicPacketCreator::StopFecProtectingPackets() { | 195 void QuicPacketCreator::StopFecProtectingPackets() { |
| 195 if (fec_group_.get() != nullptr) { | 196 if (fec_group_.get() != nullptr) { |
| 196 LOG(DFATAL) << "Cannot stop FEC protection with open FEC group."; | 197 QUIC_BUG << "Cannot stop FEC protection with open FEC group."; |
| 197 return; | 198 return; |
| 198 } | 199 } |
| 199 DCHECK(fec_protect_); | 200 DCHECK(fec_protect_); |
| 200 fec_protect_ = false; | 201 fec_protect_ = false; |
| 201 } | 202 } |
| 202 | 203 |
| 203 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() { | 204 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() { |
| 204 if (fec_group_.get() != nullptr) { | 205 if (fec_group_.get() != nullptr) { |
| 205 // Don't update any lengths when an FEC group is open, to ensure same | 206 // Don't update any lengths when an FEC group is open, to ensure same |
| 206 // packet header size in all packets within a group. | 207 // packet header size in all packets within a group. |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 // TODO(rtenneti): Change the default 64 alignas value (used the default | 459 // TODO(rtenneti): Change the default 64 alignas value (used the default |
| 459 // value from CACHELINE_SIZE). | 460 // value from CACHELINE_SIZE). |
| 460 ALIGNAS(64) char seralized_packet_buffer[kMaxPacketSize]; | 461 ALIGNAS(64) char seralized_packet_buffer[kMaxPacketSize]; |
| 461 SerializedPacket serialized_packet = | 462 SerializedPacket serialized_packet = |
| 462 SerializePacket(seralized_packet_buffer, kMaxPacketSize); | 463 SerializePacket(seralized_packet_buffer, kMaxPacketSize); |
| 463 OnSerializedPacket(&serialized_packet); | 464 OnSerializedPacket(&serialized_packet); |
| 464 } | 465 } |
| 465 | 466 |
| 466 void QuicPacketCreator::OnSerializedPacket(SerializedPacket* packet) { | 467 void QuicPacketCreator::OnSerializedPacket(SerializedPacket* packet) { |
| 467 if (packet->packet == nullptr) { | 468 if (packet->packet == nullptr) { |
| 468 LOG(DFATAL) << "Failed to SerializePacket. fec_policy:" << fec_send_policy() | 469 |
| 469 << " should_fec_protect_:" << should_fec_protect_next_packet_; | 470 QUIC_BUG << "Failed to SerializePacket. fec_policy:" << fec_send_policy() |
| 471 << " should_fec_protect_:" << should_fec_protect_next_packet_; |
| 470 delegate_->CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET, false); | 472 delegate_->CloseConnection(QUIC_FAILED_TO_SERIALIZE_PACKET, false); |
| 471 return; | 473 return; |
| 472 } | 474 } |
| 473 // There may be AckListeners interested in this packet. | 475 // There may be AckListeners interested in this packet. |
| 474 packet->listeners.swap(ack_listeners_); | 476 packet->listeners.swap(ack_listeners_); |
| 475 DCHECK(ack_listeners_.empty()); | 477 DCHECK(ack_listeners_.empty()); |
| 476 delegate_->OnSerializedPacket(packet); | 478 delegate_->OnSerializedPacket(packet); |
| 477 has_ack_ = false; | 479 has_ack_ = false; |
| 478 has_stop_waiting_ = false; | 480 has_stop_waiting_ = false; |
| 479 MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/false, | 481 MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/false, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ && | 569 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ && |
| 568 queued_frames_.size() == 1 && | 570 queued_frames_.size() == 1 && |
| 569 queued_frames_.back().type == ACK_FRAME; | 571 queued_frames_.back().type == ACK_FRAME; |
| 570 // Use the packet_size_ instead of the buffer size to ensure smaller | 572 // Use the packet_size_ instead of the buffer size to ensure smaller |
| 571 // packet sizes are properly used. | 573 // packet sizes are properly used. |
| 572 size_t encrypted_length = 0u; | 574 size_t encrypted_length = 0u; |
| 573 if (FLAGS_quic_inplace_encryption) { | 575 if (FLAGS_quic_inplace_encryption) { |
| 574 size_t length = framer_->BuildDataPacket(header, queued_frames_, | 576 size_t length = framer_->BuildDataPacket(header, queued_frames_, |
| 575 encrypted_buffer, packet_size_); | 577 encrypted_buffer, packet_size_); |
| 576 if (length == 0) { | 578 if (length == 0) { |
| 577 LOG(DFATAL) << "Failed to serialize " << queued_frames_.size() | 579 QUIC_BUG << "Failed to serialize " << queued_frames_.size() << " frames."; |
| 578 << " frames."; | |
| 579 return NoPacket(); | 580 return NoPacket(); |
| 580 } | 581 } |
| 581 | 582 |
| 582 // TODO(ianswett) Consider replacing QuicPacket with something else, since | 583 // TODO(ianswett) Consider replacing QuicPacket with something else, since |
| 583 // it's only used to provide convenience methods to FEC and encryption. | 584 // it's only used to provide convenience methods to FEC and encryption. |
| 584 QuicPacket packet(encrypted_buffer, length, | 585 QuicPacket packet(encrypted_buffer, length, |
| 585 /* owns_buffer */ false, | 586 /* owns_buffer */ false, |
| 586 header.public_header.connection_id_length, | 587 header.public_header.connection_id_length, |
| 587 header.public_header.version_flag, | 588 header.public_header.version_flag, |
| 588 header.public_header.packet_number_length); | 589 header.public_header.packet_number_length); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 600 encrypted_buffer, encrypted_buffer_len); | 601 encrypted_buffer, encrypted_buffer_len); |
| 601 } else { | 602 } else { |
| 602 // The optimized encryption algorithm implementations run faster when | 603 // The optimized encryption algorithm implementations run faster when |
| 603 // operating on aligned memory. | 604 // operating on aligned memory. |
| 604 // TODO(rtenneti): Change the default 64 alignas value (used the default | 605 // TODO(rtenneti): Change the default 64 alignas value (used the default |
| 605 // value from CACHELINE_SIZE). | 606 // value from CACHELINE_SIZE). |
| 606 ALIGNAS(64) char buffer[kMaxPacketSize]; | 607 ALIGNAS(64) char buffer[kMaxPacketSize]; |
| 607 size_t length = | 608 size_t length = |
| 608 framer_->BuildDataPacket(header, queued_frames_, buffer, packet_size_); | 609 framer_->BuildDataPacket(header, queued_frames_, buffer, packet_size_); |
| 609 if (length == 0) { | 610 if (length == 0) { |
| 610 LOG(DFATAL) << "Failed to serialize " << queued_frames_.size() | 611 QUIC_BUG << "Failed to serialize " << queued_frames_.size() << " frames."; |
| 611 << " frames."; | |
| 612 return NoPacket(); | 612 return NoPacket(); |
| 613 } | 613 } |
| 614 | 614 |
| 615 // TODO(ianswett) Consider replacing QuicPacket with something else, since | 615 // TODO(ianswett) Consider replacing QuicPacket with something else, since |
| 616 // it's only used to provide convenience methods to FEC and encryption. | 616 // it's only used to provide convenience methods to FEC and encryption. |
| 617 QuicPacket packet(buffer, length, | 617 QuicPacket packet(buffer, length, |
| 618 /* owns_buffer */ false, | 618 /* owns_buffer */ false, |
| 619 header.public_header.connection_id_length, | 619 header.public_header.connection_id_length, |
| 620 header.public_header.version_flag, | 620 header.public_header.version_flag, |
| 621 header.public_header.packet_number_length); | 621 header.public_header.packet_number_length); |
| 622 OnBuiltFecProtectedPayload(header, packet.FecProtectedData()); | 622 OnBuiltFecProtectedPayload(header, packet.FecProtectedData()); |
| 623 | 623 |
| 624 // Because of possible truncation, we can't be confident that our | 624 // Because of possible truncation, we can't be confident that our |
| 625 // packet size calculation worked correctly. | 625 // packet size calculation worked correctly. |
| 626 if (!possibly_truncated_by_length) { | 626 if (!possibly_truncated_by_length) { |
| 627 DCHECK_EQ(packet_size_, length); | 627 DCHECK_EQ(packet_size_, length); |
| 628 } | 628 } |
| 629 // Immediately encrypt the packet, to ensure we don't encrypt the same | 629 // Immediately encrypt the packet, to ensure we don't encrypt the same |
| 630 // packet number multiple times. | 630 // packet number multiple times. |
| 631 encrypted_length = | 631 encrypted_length = |
| 632 framer_->EncryptPayload(encryption_level_, packet_number_, packet, | 632 framer_->EncryptPayload(encryption_level_, packet_number_, packet, |
| 633 encrypted_buffer, encrypted_buffer_len); | 633 encrypted_buffer, encrypted_buffer_len); |
| 634 } | 634 } |
| 635 if (encrypted_length == 0) { | 635 if (encrypted_length == 0) { |
| 636 LOG(DFATAL) << "Failed to encrypt packet number " << packet_number_; | 636 QUIC_BUG << "Failed to encrypt packet number " << packet_number_; |
| 637 return NoPacket(); | 637 return NoPacket(); |
| 638 } | 638 } |
| 639 | 639 |
| 640 // Update |needs_padding_| flag of |queued_retransmittable_frames_| here, and | 640 // Update |needs_padding_| flag of |queued_retransmittable_frames_| here, and |
| 641 // not in AddFrame, because when the first padded frame is added to the queue, | 641 // not in AddFrame, because when the first padded frame is added to the queue, |
| 642 // it might not be retransmittable, and hence the flag would end up being not | 642 // it might not be retransmittable, and hence the flag would end up being not |
| 643 // set. | 643 // set. |
| 644 if (queued_retransmittable_frames_.get() != nullptr) { | 644 if (queued_retransmittable_frames_.get() != nullptr) { |
| 645 queued_retransmittable_frames_->set_needs_padding(needs_padding_); | 645 queued_retransmittable_frames_->set_needs_padding(needs_padding_); |
| 646 } | 646 } |
| 647 | 647 |
| 648 packet_size_ = 0; | 648 packet_size_ = 0; |
| 649 queued_frames_.clear(); | 649 queued_frames_.clear(); |
| 650 needs_padding_ = false; | 650 needs_padding_ = false; |
| 651 return SerializedPacket(current_path_, header.packet_number, | 651 return SerializedPacket(current_path_, header.packet_number, |
| 652 header.public_header.packet_number_length, | 652 header.public_header.packet_number_length, |
| 653 encrypted_buffer, encrypted_length, | 653 encrypted_buffer, encrypted_length, |
| 654 /* owns_buffer*/ false, | 654 /* owns_buffer*/ false, |
| 655 QuicFramer::GetPacketEntropyHash(header), | 655 QuicFramer::GetPacketEntropyHash(header), |
| 656 queued_retransmittable_frames_.release(), has_ack_, | 656 queued_retransmittable_frames_.release(), has_ack_, |
| 657 has_stop_waiting_, encryption_level_); | 657 has_stop_waiting_, encryption_level_); |
| 658 } | 658 } |
| 659 | 659 |
| 660 SerializedPacket QuicPacketCreator::SerializeFec(char* buffer, | 660 SerializedPacket QuicPacketCreator::SerializeFec(char* buffer, |
| 661 size_t buffer_len) { | 661 size_t buffer_len) { |
| 662 DCHECK_LT(0u, buffer_len); | 662 DCHECK_LT(0u, buffer_len); |
| 663 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) { | 663 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) { |
| 664 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group."; | 664 QUIC_BUG << "SerializeFEC called but no group or zero packets in group."; |
| 665 // TODO(jri): Make this a public method of framer? | 665 // TODO(jri): Make this a public method of framer? |
| 666 return NoPacket(); | 666 return NoPacket(); |
| 667 } | 667 } |
| 668 DCHECK_EQ(0u, queued_frames_.size()); | 668 DCHECK_EQ(0u, queued_frames_.size()); |
| 669 QuicPacketHeader header; | 669 QuicPacketHeader header; |
| 670 FillPacketHeader(fec_group_->FecGroupNumber(), true, &header); | 670 FillPacketHeader(fec_group_->FecGroupNumber(), true, &header); |
| 671 scoped_ptr<QuicPacket> packet( | 671 scoped_ptr<QuicPacket> packet( |
| 672 framer_->BuildFecPacket(header, fec_group_->PayloadParity())); | 672 framer_->BuildFecPacket(header, fec_group_->PayloadParity())); |
| 673 fec_group_.reset(nullptr); | 673 fec_group_.reset(nullptr); |
| 674 packet_size_ = 0; | 674 packet_size_ = 0; |
| 675 LOG_IF(DFATAL, packet == nullptr) | 675 LOG_IF(DFATAL, packet == nullptr) |
| 676 << "Failed to serialize fec packet for group:" | 676 << "Failed to serialize fec packet for group:" |
| 677 << fec_group_->FecGroupNumber(); | 677 << fec_group_->FecGroupNumber(); |
| 678 DCHECK_GE(max_packet_length_, packet->length()); | 678 DCHECK_GE(max_packet_length_, packet->length()); |
| 679 // Immediately encrypt the packet, to ensure we don't encrypt the same packet | 679 // Immediately encrypt the packet, to ensure we don't encrypt the same packet |
| 680 // packet number multiple times. | 680 // packet number multiple times. |
| 681 size_t encrypted_length = framer_->EncryptPayload( | 681 size_t encrypted_length = framer_->EncryptPayload( |
| 682 encryption_level_, packet_number_, *packet, buffer, buffer_len); | 682 encryption_level_, packet_number_, *packet, buffer, buffer_len); |
| 683 if (encrypted_length == 0) { | 683 if (encrypted_length == 0) { |
| 684 LOG(DFATAL) << "Failed to encrypt packet number " << packet_number_; | 684 QUIC_BUG << "Failed to encrypt packet number " << packet_number_; |
| 685 return NoPacket(); | 685 return NoPacket(); |
| 686 } | 686 } |
| 687 SerializedPacket serialized(current_path_, header.packet_number, | 687 SerializedPacket serialized(current_path_, header.packet_number, |
| 688 header.public_header.packet_number_length, buffer, | 688 header.public_header.packet_number_length, buffer, |
| 689 encrypted_length, /* owns_buffer */ false, | 689 encrypted_length, /* owns_buffer */ false, |
| 690 QuicFramer::GetPacketEntropyHash(header), nullptr, | 690 QuicFramer::GetPacketEntropyHash(header), nullptr, |
| 691 false, false, encryption_level_); | 691 false, false, encryption_level_); |
| 692 serialized.is_fec_packet = true; | 692 serialized.is_fec_packet = true; |
| 693 return serialized; | 693 return serialized; |
| 694 } | 694 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 return true; | 734 return true; |
| 735 } | 735 } |
| 736 } | 736 } |
| 737 | 737 |
| 738 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, | 738 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, |
| 739 bool save_retransmittable_frames) { | 739 bool save_retransmittable_frames) { |
| 740 DVLOG(1) << "Adding frame: " << frame; | 740 DVLOG(1) << "Adding frame: " << frame; |
| 741 if (FLAGS_quic_never_write_unencrypted_data && frame.type == STREAM_FRAME && | 741 if (FLAGS_quic_never_write_unencrypted_data && frame.type == STREAM_FRAME && |
| 742 frame.stream_frame->stream_id != kCryptoStreamId && | 742 frame.stream_frame->stream_id != kCryptoStreamId && |
| 743 encryption_level_ == ENCRYPTION_NONE) { | 743 encryption_level_ == ENCRYPTION_NONE) { |
| 744 LOG(DFATAL) << "Cannot send stream data without encryption."; | 744 QUIC_BUG << "Cannot send stream data without encryption."; |
| 745 delegate_->CloseConnection(QUIC_UNENCRYPTED_STREAM_DATA, false); | 745 delegate_->CloseConnection(QUIC_UNENCRYPTED_STREAM_DATA, false); |
| 746 return false; | 746 return false; |
| 747 } | 747 } |
| 748 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); | 748 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); |
| 749 | 749 |
| 750 size_t frame_len = framer_->GetSerializedFrameLength( | 750 size_t frame_len = framer_->GetSerializedFrameLength( |
| 751 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, | 751 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, |
| 752 packet_number_length_); | 752 packet_number_length_); |
| 753 if (frame_len == 0) { | 753 if (frame_len == 0) { |
| 754 // Current open packet is full. | 754 // Current open packet is full. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 | 853 |
| 854 void QuicPacketCreator::SetCurrentPath( | 854 void QuicPacketCreator::SetCurrentPath( |
| 855 QuicPathId path_id, | 855 QuicPathId path_id, |
| 856 QuicPacketNumber least_packet_awaited_by_peer, | 856 QuicPacketNumber least_packet_awaited_by_peer, |
| 857 QuicPacketCount max_packets_in_flight) { | 857 QuicPacketCount max_packets_in_flight) { |
| 858 if (current_path_ == path_id) { | 858 if (current_path_ == path_id) { |
| 859 return; | 859 return; |
| 860 } | 860 } |
| 861 | 861 |
| 862 if (HasPendingFrames()) { | 862 if (HasPendingFrames()) { |
| 863 LOG(DFATAL) | 863 QUIC_BUG << "Unable to change paths when a packet is under construction."; |
| 864 << "Unable to change paths when a packet is under construction."; | |
| 865 return; | 864 return; |
| 866 } | 865 } |
| 867 | 866 |
| 868 // Send FEC packet and close FEC group. | 867 // Send FEC packet and close FEC group. |
| 869 MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true, | 868 MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true, |
| 870 /*is_fec_timeout=*/false); | 869 /*is_fec_timeout=*/false); |
| 871 // Save current packet number and load switching path's packet number. | 870 // Save current packet number and load switching path's packet number. |
| 872 multipath_packet_number_[current_path_] = packet_number_; | 871 multipath_packet_number_[current_path_] = packet_number_; |
| 873 hash_map<QuicPathId, QuicPacketNumber>::iterator it = | 872 hash_map<QuicPathId, QuicPacketNumber>::iterator it = |
| 874 multipath_packet_number_.find(path_id); | 873 multipath_packet_number_.find(path_id); |
| 875 // If path_id is not in the map, it's a new path. Set packet_number to 0. | 874 // If path_id is not in the map, it's a new path. Set packet_number to 0. |
| 876 packet_number_ = it == multipath_packet_number_.end() ? 0 : it->second; | 875 packet_number_ = it == multipath_packet_number_.end() ? 0 : it->second; |
| 877 current_path_ = path_id; | 876 current_path_ = path_id; |
| 878 // Switching path needs to update packet number length. | 877 // Switching path needs to update packet number length. |
| 879 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight); | 878 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight); |
| 880 } | 879 } |
| 881 | 880 |
| 882 } // namespace net | 881 } // namespace net |
| OLD | NEW |