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 |