gfe-relnote: Remove QuicPacketGenerator. Deprecate gfe2_reloadable_flag_quic_combine_generator_and_creator. PiperOrigin-RevId: 278697040 Change-Id: I0358b83acdbb8c129b4decc40b237f3beb3b115a
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc index 64f7eea..adbca34 100644 --- a/quic/core/quic_connection.cc +++ b/quic/core/quic_connection.cc
@@ -24,7 +24,6 @@ #include "net/third_party/quiche/src/quic/core/quic_config.h" #include "net/third_party/quiche/src/quic/core/quic_connection_id.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" -#include "net/third_party/quiche/src/quic/core/quic_packet_generator.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" @@ -294,10 +293,7 @@ &arena_)), visitor_(nullptr), debug_visitor_(nullptr), - packet_generator_(server_connection_id_, - &framer_, - random_generator_, - this), + packet_creator_(server_connection_id_, &framer_, random_generator_, this), idle_network_timeout_(QuicTime::Delta::Infinite()), handshake_timeout_(QuicTime::Delta::Infinite()), time_of_first_packet_sent_after_receiving_(QuicTime::Zero()), @@ -431,7 +427,7 @@ sent_packet_manager_.SetFromConfig(config); if (config.HasReceivedBytesForConnectionId() && can_truncate_connection_ids_) { - packet_generator_.SetServerConnectionIdLength( + packet_creator_.SetServerConnectionIdLength( config.ReceivedBytesForConnectionId()); } max_undecryptable_packets_ = config.max_undecryptable_packets(); @@ -665,8 +661,8 @@ << ", received token " << QuicTextUtils::HexEncode(retry_token); server_connection_id_ = new_connection_id; - packet_generator_.SetServerConnectionId(server_connection_id_); - packet_generator_.SetRetryToken(retry_token); + packet_creator_.SetServerConnectionId(server_connection_id_); + packet_creator_.SetRetryToken(retry_token); // Reinstall initial crypters because the connection ID changed. InstallInitialCrypters(server_connection_id_); @@ -759,7 +755,7 @@ GetServerConnectionIdAsRecipient(header, perspective_)) || PacketCanReplaceConnectionId(header, perspective_)); - if (packet_generator_.HasPendingFrames()) { + if (packet_creator_.HasPendingFrames()) { // Incoming packets may change a queued ACK frame. const std::string error_details = "Pending frames must be serialized before incoming packets are " @@ -1567,7 +1563,7 @@ framer_.supported_versions()) << "}, " << (ietf_quic ? "" : "!") << "ietf_quic"; std::unique_ptr<QuicEncryptedPacket> version_packet( - packet_generator_.SerializeVersionNegotiationPacket( + packet_creator_.SerializeVersionNegotiationPacket( ietf_quic, has_length_prefix, framer_.supported_versions())); QUIC_DVLOG(2) << ENDPOINT << "Sending version negotiation packet: {" << ParsedQuicVersionVectorToString(framer_.supported_versions()) @@ -1604,7 +1600,7 @@ return 0; } ScopedPacketFlusher flusher(this); - return packet_generator_.ConsumeCryptoData(level, write_length, offset); + return packet_creator_.ConsumeCryptoData(level, write_length, offset); } QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id, @@ -1622,7 +1618,7 @@ // packet (a handshake packet from client to server could result in a REJ or a // SHLO from the server, leading to two different decrypters at the server.) ScopedPacketFlusher flusher(this); - return packet_generator_.ConsumeData(id, write_length, offset, state); + return packet_creator_.ConsumeData(id, write_length, offset, state); } bool QuicConnection::SendControlFrame(const QuicFrame& frame) { @@ -1640,14 +1636,14 @@ } ScopedPacketFlusher flusher(this); const bool consumed = - packet_generator_.ConsumeRetransmittableControlFrame(frame); + packet_creator_.ConsumeRetransmittableControlFrame(frame); if (!consumed) { QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame; return false; } if (frame.type == PING_FRAME) { // Flush PING frame immediately. - packet_generator_.FlushAllQueuedFrames(); + packet_creator_.FlushCurrentPacket(); if (debug_visitor_ != nullptr) { debug_visitor_->OnPingSent(); } @@ -1666,9 +1662,9 @@ return; } // Flush stream frames of reset stream. - if (packet_generator_.HasPendingStreamFramesOfStream(id)) { + if (packet_creator_.HasPendingStreamFramesOfStream(id)) { ScopedPacketFlusher flusher(this); - packet_generator_.FlushAllQueuedFrames(); + packet_creator_.FlushCurrentPacket(); } // Remove all queued packets which only contain data for the reset stream. @@ -1711,7 +1707,7 @@ stats_.srtt_us = srtt.ToMicroseconds(); stats_.estimated_bandwidth = sent_packet_manager_.BandwidthEstimate(); - stats_.max_packet_size = packet_generator_.GetCurrentMaxPacketLength(); + stats_.max_packet_size = packet_creator_.max_packet_length(); stats_.max_received_packet_size = largest_received_packet_size_; return stats_; } @@ -1950,7 +1946,7 @@ << server_connection_id_ << " with " << header.source_connection_id; server_connection_id_ = header.source_connection_id; - packet_generator_.SetServerConnectionId(server_connection_id_); + packet_creator_.SetServerConnectionId(server_connection_id_); } if (!ValidateReceivedPacketNumber(header.packet_number)) { @@ -1965,7 +1961,7 @@ // it should stop sending version since the version negotiation is done. // IETF QUIC stops sending version once encryption level switches to // forward secure. - packet_generator_.StopSendingVersion(); + packet_creator_.StopSendingVersion(); } version_negotiated_ = true; visitor_->OnSuccessfulVersionNegotiation(version()); @@ -1981,7 +1977,7 @@ if (perspective_ == Perspective::IS_SERVER && encryption_level_ == ENCRYPTION_INITIAL && - last_size_ > packet_generator_.GetCurrentMaxPacketLength()) { + last_size_ > packet_creator_.max_packet_length()) { SetMaxPacketLength(last_size_); } return true; @@ -2243,7 +2239,7 @@ packet->encrypted_length > long_term_mtu_; DCHECK_LE(encrypted_length, kMaxOutgoingPacketSize); if (!looks_like_mtu_probe) { - DCHECK_LE(encrypted_length, packet_generator_.GetCurrentMaxPacketLength()); + DCHECK_LE(encrypted_length, packet_creator_.max_packet_length()); } QUIC_DVLOG(1) << ENDPOINT << "Sending packet " << packet_number << " : " << (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA @@ -2279,7 +2275,7 @@ if (!coalesced_packet_.MaybeCoalescePacket( *packet, self_address(), peer_address(), helper_->GetStreamSendBufferAllocator(), - packet_generator_.GetCurrentMaxPacketLength())) { + packet_creator_.max_packet_length())) { // Failed to coalesce packet, flush current coalesced packet. if (!FlushCoalescedPacket()) { // Failed to flush coalesced packet, write error has been handled. @@ -2288,7 +2284,7 @@ if (!coalesced_packet_.MaybeCoalescePacket( *packet, self_address(), peer_address(), helper_->GetStreamSendBufferAllocator(), - packet_generator_.GetCurrentMaxPacketLength())) { + packet_creator_.max_packet_length())) { // Failed to coalesce packet even it is the only packet, raise a write // error. QUIC_DLOG(ERROR) << ENDPOINT << "Failed to coalesce packet"; @@ -2300,7 +2296,7 @@ QUIC_DVLOG(1) << ENDPOINT << "Trying to set soft max packet length to " << coalesced_packet_.max_packet_length() - coalesced_packet_.length(); - packet_generator_.SetSoftMaxPacketLength( + packet_creator_.SetSoftMaxPacketLength( coalesced_packet_.max_packet_length() - coalesced_packet_.length()); } break; @@ -2422,7 +2418,7 @@ // The packet number length must be updated after OnPacketSent, because it // may change the packet number length in packet. - packet_generator_.UpdatePacketNumberLength( + packet_creator_.UpdatePacketNumberLength( sent_packet_manager_.GetLeastUnacked(), sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length())); @@ -2644,7 +2640,7 @@ PopulateStopWaitingFrame(&stop_waiting); frames.push_back(QuicFrame(stop_waiting)); } - if (!packet_generator_.FlushAckFrame(frames)) { + if (!packet_creator_.FlushAckFrame(frames)) { return; } ResetAckStates(); @@ -2653,7 +2649,7 @@ return; } consecutive_num_packets_with_no_retransmittable_frames_ = 0; - if (packet_generator_.HasRetransmittableFrames() || + if (packet_creator_.HasPendingRetransmittableFrames() || visitor_->WillingAndAbleToWrite()) { // There are pending retransmittable frames. return; @@ -2672,7 +2668,7 @@ (sent_packet_manager_.handshake_mode_disabled() && !sent_packet_manager_.handshake_confirmed())); const QuicPacketNumber previous_created_packet_number = - packet_generator_.packet_number(); + packet_creator_.packet_number(); if (close_connection_after_five_rtos_ && sent_packet_manager_.GetConsecutiveRtoCount() >= 4) { // Close on the 5th consecutive RTO, so after 4 previous RTOs have occurred. @@ -2696,7 +2692,7 @@ sent_packet_manager_.pending_timer_transmission_count() == 1) { // Skip a packet number when a single PTO packet is sent to elicit an // immediate ACK. - packet_generator_.SkipNPacketNumbers( + packet_creator_.SkipNPacketNumbers( 1, sent_packet_manager_.GetLeastUnacked(), sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length())); } @@ -2717,7 +2713,7 @@ WriteIfNotBlocked(); } - if (packet_generator_.packet_number() == previous_created_packet_number && + if (packet_creator_.packet_number() == previous_created_packet_number && (retransmission_mode == QuicSentPacketManager::TLP_MODE || retransmission_mode == QuicSentPacketManager::RTO_MODE || retransmission_mode == QuicSentPacketManager::PTO_MODE) && @@ -2743,12 +2739,12 @@ // When timer fires in TLP or RTO mode, ensure 1) at least one packet is // created, or there is data to send and available credit (such that // packets will be sent eventually). - QUIC_BUG_IF(packet_generator_.packet_number() == + QUIC_BUG_IF(packet_creator_.packet_number() == previous_created_packet_number && (!visitor_->WillingAndAbleToWrite() || sent_packet_manager_.pending_timer_transmission_count() == 0u)) << "retransmission_mode: " << retransmission_mode - << ", packet_number: " << packet_generator_.packet_number() + << ", packet_number: " << packet_creator_.packet_number() << ", session has data to write: " << visitor_->WillingAndAbleToWrite() << ", writer is blocked: " << writer_->IsWriteBlocked() << ", pending_timer_transmission_count: " @@ -2766,26 +2762,26 @@ void QuicConnection::SetEncrypter(EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) { - packet_generator_.SetEncrypter(level, std::move(encrypter)); + packet_creator_.SetEncrypter(level, std::move(encrypter)); } void QuicConnection::SetDiversificationNonce( const DiversificationNonce& nonce) { DCHECK_EQ(Perspective::IS_SERVER, perspective_); - packet_generator_.SetDiversificationNonce(nonce); + packet_creator_.SetDiversificationNonce(nonce); } void QuicConnection::SetDefaultEncryptionLevel(EncryptionLevel level) { QUIC_DVLOG(1) << ENDPOINT << "Setting default encryption level from " << EncryptionLevelToString(encryption_level_) << " to " << EncryptionLevelToString(level); - if (level != encryption_level_ && packet_generator_.HasPendingFrames()) { + if (level != encryption_level_ && packet_creator_.HasPendingFrames()) { // Flush all queued frames when encryption level changes. ScopedPacketFlusher flusher(this); - packet_generator_.FlushAllQueuedFrames(); + packet_creator_.FlushCurrentPacket(); } encryption_level_ = level; - packet_generator_.set_encryption_level(level); + packet_creator_.set_encryption_level(level); } void QuicConnection::SetDecrypter(EncryptionLevel level, @@ -2856,7 +2852,7 @@ while (connected_ && !undecryptable_packets_.empty()) { // Making sure there is no pending frames when processing next undecrypted // packet because the queued ack frame may change. - packet_generator_.FlushAllQueuedFrames(); + packet_creator_.FlushCurrentPacket(); if (!connected_) { return; } @@ -2899,7 +2895,7 @@ while (connected_ && !received_coalesced_packets_.empty()) { // Making sure there are no pending frames when processing the next // coalesced packet because the queued ack frame may change. - packet_generator_.FlushAllQueuedFrames(); + packet_creator_.FlushCurrentPacket(); if (!connected_) { return; } @@ -2966,8 +2962,8 @@ frame = new QuicConnectionCloseFrame(transport_version(), error, details, framer_.current_received_frame_type()); - packet_generator_.ConsumeRetransmittableControlFrame(QuicFrame(frame)); - packet_generator_.FlushAllQueuedFrames(); + packet_creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame)); + packet_creator_.FlushCurrentPacket(); if (version().CanSendCoalescedPackets()) { FlushCoalescedPacket(); } @@ -3002,8 +2998,8 @@ auto* frame = new QuicConnectionCloseFrame(transport_version(), error, details, framer_.current_received_frame_type()); - packet_generator_.ConsumeRetransmittableControlFrame(QuicFrame(frame)); - packet_generator_.FlushAllQueuedFrames(); + packet_creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame)); + packet_creator_.FlushCurrentPacket(); if (!version().CanSendCoalescedPackets()) { ClearQueuedPackets(); } @@ -3059,17 +3055,17 @@ } QuicByteCount QuicConnection::max_packet_length() const { - return packet_generator_.GetCurrentMaxPacketLength(); + return packet_creator_.max_packet_length(); } void QuicConnection::SetMaxPacketLength(QuicByteCount length) { long_term_mtu_ = length; - packet_generator_.SetMaxPacketLength(GetLimitedMaxPacketSize(length)); + packet_creator_.SetMaxPacketLength(GetLimitedMaxPacketSize(length)); } bool QuicConnection::HasQueuedData() const { return pending_version_negotiation_packet_ || !queued_packets_.empty() || - packet_generator_.HasPendingFrames() || !buffered_packets_.empty(); + packet_creator_.HasPendingFrames() || !buffered_packets_.empty(); } bool QuicConnection::CanWriteStreamData() { @@ -3226,7 +3222,7 @@ } void QuicConnection::SetRetransmissionAlarm() { - if (packet_generator_.PacketFlusherAttached()) { + if (packet_creator_.PacketFlusherAttached()) { pending_retransmission_alarm_ = true; return; } @@ -3296,9 +3292,9 @@ return; } - if (!connection_->packet_generator_.PacketFlusherAttached()) { + if (!connection_->packet_creator_.PacketFlusherAttached()) { flush_and_set_pending_retransmission_alarm_on_delete_ = true; - connection->packet_generator_.AttachPacketFlusher(); + connection->packet_creator_.AttachPacketFlusher(); } } @@ -3337,7 +3333,7 @@ connection_->SendAck(); } } - connection_->packet_generator_.Flush(); + connection_->packet_creator_.Flush(); if (connection_->version().CanSendCoalescedPackets()) { connection_->FlushCoalescedPacket(); } @@ -3371,7 +3367,7 @@ } } DCHECK_EQ(flush_and_set_pending_retransmission_alarm_on_delete_, - !connection_->packet_generator_.PacketFlusherAttached()); + !connection_->packet_creator_.PacketFlusherAttached()); } QuicConnection::BufferedPacket::BufferedPacket( @@ -3454,7 +3450,7 @@ DCHECK_EQ(target_mtu, GetLimitedMaxPacketSize(target_mtu)); // Send the probe. - packet_generator_.GenerateMtuDiscoveryPacket(target_mtu); + packet_creator_.GenerateMtuDiscoveryPacket(target_mtu); } // TODO(zhongyi): change this method to generate a connectivity probing packet @@ -3509,7 +3505,7 @@ if (!VersionHasIetfQuicFrames(transport_version())) { // Non-IETF QUIC, generate a padded ping regardless of whether this is a // request or a response. - probing_packet = packet_generator_.SerializeConnectivityProbingPacket(); + probing_packet = packet_creator_.SerializeConnectivityProbingPacket(); } else { if (is_response) { // Respond using IETF QUIC PATH_RESPONSE frame @@ -3517,14 +3513,14 @@ // Pad the response if the request was a google connectivity probe // (padded). probing_packet = - packet_generator_.SerializePathResponseConnectivityProbingPacket( + packet_creator_.SerializePathResponseConnectivityProbingPacket( received_path_challenge_payloads_, /* is_padded = */ true); received_path_challenge_payloads_.clear(); } else { // Do not pad the response if the path challenge was not a google // connectivity probe. probing_packet = - packet_generator_.SerializePathResponseConnectivityProbingPacket( + packet_creator_.SerializePathResponseConnectivityProbingPacket( received_path_challenge_payloads_, /* is_padded = */ false); received_path_challenge_payloads_.clear(); @@ -3534,7 +3530,7 @@ transmitted_connectivity_probe_payload_ = std::make_unique<QuicPathFrameBuffer>(); probing_packet = - packet_generator_.SerializePathChallengeConnectivityProbingPacket( + packet_creator_.SerializePathChallengeConnectivityProbingPacket( transmitted_connectivity_probe_payload_.get()); if (!probing_packet) { transmitted_connectivity_probe_payload_ = nullptr; @@ -3847,7 +3843,7 @@ } void QuicConnection::SetTransmissionType(TransmissionType type) { - packet_generator_.SetTransmissionType(type); + packet_creator_.SetTransmissionType(type); } void QuicConnection::UpdateReleaseTimeIntoFuture() { @@ -3882,15 +3878,15 @@ return MESSAGE_STATUS_BLOCKED; } ScopedPacketFlusher flusher(this); - return packet_generator_.AddMessageFrame(message_id, message); + return packet_creator_.AddMessageFrame(message_id, message); } QuicPacketLength QuicConnection::GetCurrentLargestMessagePayload() const { - return packet_generator_.GetCurrentLargestMessagePayload(); + return packet_creator_.GetCurrentLargestMessagePayload(); } QuicPacketLength QuicConnection::GetGuaranteedLargestMessagePayload() const { - return packet_generator_.GetGuaranteedLargestMessagePayload(); + return packet_creator_.GetGuaranteedLargestMessagePayload(); } uint32_t QuicConnection::cipher_id() const { @@ -3953,7 +3949,7 @@ QuicFrames frames; frames.push_back(uber_received_packet_manager_.GetUpdatedAckFrame( static_cast<PacketNumberSpace>(i), clock_->ApproximateNow())); - const bool flushed = packet_generator_.FlushAckFrame(frames); + const bool flushed = packet_creator_.FlushAckFrame(frames); if (!flushed) { // Connection is write blocked. QUIC_BUG_IF(!writer_->IsWriteBlocked()) @@ -3979,7 +3975,7 @@ return; } consecutive_num_packets_with_no_retransmittable_frames_ = 0; - if (packet_generator_.HasRetransmittableFrames() || + if (packet_creator_.HasPendingRetransmittableFrames() || visitor_->WillingAndAbleToWrite()) { // There are pending retransmittable frames. return; @@ -3999,7 +3995,7 @@ } QUIC_DVLOG(1) << ENDPOINT << "Sending coalesced packet"; char buffer[kMaxOutgoingPacketSize]; - const size_t length = packet_generator_.SerializeCoalescedPacket( + const size_t length = packet_creator_.SerializeCoalescedPacket( coalesced_packet_, buffer, coalesced_packet_.max_packet_length()); if (length == 0) { return false; @@ -4176,7 +4172,7 @@ << client_connection_id_ << " for connection with server connection ID " << server_connection_id_; - packet_generator_.SetClientConnectionId(client_connection_id_); + packet_creator_.SetClientConnectionId(client_connection_id_); framer_.SetExpectedClientConnectionIdLength(client_connection_id_.length()); }
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h index 7bbd931..d858e3a 100644 --- a/quic/core/quic_connection.h +++ b/quic/core/quic_connection.h
@@ -37,7 +37,6 @@ #include "net/third_party/quiche/src/quic/core/quic_mtu_discovery.h" #include "net/third_party/quiche/src/quic/core/quic_one_block_arena.h" #include "net/third_party/quiche/src/quic/core/quic_packet_creator.h" -#include "net/third_party/quiche/src/quic/core/quic_packet_generator.h" #include "net/third_party/quiche/src/quic/core/quic_packet_writer.h" #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h" @@ -513,12 +512,10 @@ void OnAuthenticatedIetfStatelessResetPacket( const QuicIetfStatelessResetPacket& packet) override; - // QuicPacketGenerator::DelegateInterface + // QuicPacketCreator::DelegateInterface bool ShouldGeneratePacket(HasRetransmittableData retransmittable, IsHandshake handshake) override; const QuicFrames MaybeBundleAckOpportunistically() override; - - // QuicPacketCreator::DelegateInterface char* GetPacketBuffer() override; void OnSerializedPacket(SerializedPacket* packet) override; void OnUnrecoverableError(QuicErrorCode error, @@ -566,7 +563,7 @@ } // Used in Chromium, but not internally. void set_creator_debug_delegate(QuicPacketCreator::DebugDelegate* visitor) { - packet_generator_.set_debug_delegate(visitor); + packet_creator_.set_debug_delegate(visitor); } const QuicSocketAddress& self_address() const { return self_address_; } const QuicSocketAddress& peer_address() const { return direct_peer_address_; } @@ -784,9 +781,7 @@ const QuicFramer& framer() const { return framer_; } - const QuicPacketGenerator& packet_generator() const { - return packet_generator_; - } + const QuicPacketCreator& packet_creator() const { return packet_creator_; } EncryptionLevel encryption_level() const { return encryption_level_; } EncryptionLevel last_decrypted_level() const { @@ -811,11 +806,11 @@ // can only be set to false if there is some other mechanism of preventing // amplification attacks, such as ICE (plus its a non-standard quic). void set_fully_pad_crypto_handshake_packets(bool new_value) { - packet_generator_.set_fully_pad_crypto_handshake_packets(new_value); + packet_creator_.set_fully_pad_crypto_handshake_packets(new_value); } bool fully_pad_during_crypto_handshake() const { - return packet_generator_.fully_pad_crypto_handshake_packets(); + return packet_creator_.fully_pad_crypto_handshake_packets(); } size_t min_received_before_ack_decimation() const; @@ -1344,7 +1339,7 @@ QuicConnectionVisitorInterface* visitor_; QuicConnectionDebugVisitor* debug_visitor_; - QuicPacketGenerator packet_generator_; + QuicPacketCreator packet_creator_; // Network idle time before this connection is closed. QuicTime::Delta idle_network_timeout_;
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc index 5a2e0ef..5194a9c 100644 --- a/quic/core/quic_connection_test.cc +++ b/quic/core/quic_connection_test.cc
@@ -36,7 +36,6 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h" -#include "net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h" @@ -969,7 +968,6 @@ Perspective::IS_CLIENT, version()), creator_(QuicConnectionPeer::GetPacketCreator(&connection_)), - generator_(QuicConnectionPeer::GetPacketGenerator(&connection_)), manager_(QuicConnectionPeer::GetSentPacketManager(&connection_)), frame1_(0, false, 0, QuicStringPiece(data1)), frame2_(0, false, 3, QuicStringPiece(data2)), @@ -1625,7 +1623,6 @@ std::unique_ptr<TestPacketWriter> writer_; TestConnection connection_; QuicPacketCreator* creator_; - QuicPacketGenerator* generator_; QuicSentPacketManager* manager_; StrictMock<MockQuicConnectionVisitor> visitor_;
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc index ac467a2..b64ed3f 100644 --- a/quic/core/quic_packet_creator.cc +++ b/quic/core/quic_packet_creator.cc
@@ -125,14 +125,9 @@ flusher_attached_(false), fully_pad_crypto_handshake_packets_(true), latched_hard_max_packet_length_(0), - combine_generator_and_creator_( - GetQuicReloadableFlag(quic_combine_generator_and_creator)), populate_nonretransmittable_frames_( GetQuicReloadableFlag(quic_populate_nonretransmittable_frames)) { SetMaxPacketLength(kDefaultMaxPacketSize); - if (combine_generator_and_creator_) { - QUIC_RELOADABLE_FLAG_COUNT(quic_combine_generator_and_creator); - } if (populate_nonretransmittable_frames_) { QUIC_RELOADABLE_FLAG_COUNT(quic_populate_nonretransmittable_frames); } @@ -1098,7 +1093,6 @@ bool QuicPacketCreator::ConsumeRetransmittableControlFrame( const QuicFrame& frame) { - DCHECK(combine_generator_and_creator_); QUIC_BUG_IF(IsControlFrame(frame.type) && !GetControlFrameId(frame)) << "Adding a control frame with no control frame id: " << frame; DCHECK(QuicUtils::IsRetransmittableFrame(frame.type)) << frame; @@ -1126,7 +1120,6 @@ size_t write_length, QuicStreamOffset offset, StreamSendingState state) { - DCHECK(combine_generator_and_creator_); QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when " "generator tries to write stream data."; bool has_handshake = QuicUtils::IsCryptoStreamId(transport_version(), id); @@ -1218,7 +1211,6 @@ QuicStreamOffset offset, bool fin, size_t total_bytes_consumed) { - DCHECK(combine_generator_and_creator_); DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id)); while (total_bytes_consumed < write_length && @@ -1239,7 +1231,6 @@ size_t QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level, size_t write_length, QuicStreamOffset offset) { - DCHECK(combine_generator_and_creator_); QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when " "generator tries to write crypto data."; MaybeBundleAckOpportunistically(); @@ -1277,7 +1268,6 @@ } void QuicPacketCreator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) { - DCHECK(combine_generator_and_creator_); // MTU discovery frames must be sent by themselves. if (!CanSetMaxPacketLength()) { QUIC_BUG << "MTU discovery packets should only be sent when no other " @@ -1305,7 +1295,6 @@ } void QuicPacketCreator::MaybeBundleAckOpportunistically() { - DCHECK(combine_generator_and_creator_); if (has_ack()) { // Ack already queued, nothing to do. return; @@ -1321,7 +1310,6 @@ } bool QuicPacketCreator::FlushAckFrame(const QuicFrames& frames) { - DCHECK(combine_generator_and_creator_); QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when " "generator tries to send ACK frame."; for (const auto& frame : frames) { @@ -1346,12 +1334,10 @@ } void QuicPacketCreator::AddRandomPadding() { - DCHECK(combine_generator_and_creator_); AddPendingPadding(random_->RandUint64() % kMaxNumRandomPaddingBytes + 1); } void QuicPacketCreator::AttachPacketFlusher() { - DCHECK(combine_generator_and_creator_); flusher_attached_ = true; if (!write_start_packet_number_.IsInitialized()) { write_start_packet_number_ = NextSendingPacketNumber(); @@ -1359,7 +1345,6 @@ } void QuicPacketCreator::Flush() { - DCHECK(combine_generator_and_creator_); FlushCurrentPacket(); SendRemainingPendingPadding(); flusher_attached_ = false; @@ -1377,7 +1362,6 @@ } void QuicPacketCreator::SendRemainingPendingPadding() { - DCHECK(combine_generator_and_creator_); while ( pending_padding_bytes() > 0 && !HasPendingFrames() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) { @@ -1386,7 +1370,6 @@ } void QuicPacketCreator::SetServerConnectionIdLength(uint32_t length) { - DCHECK(combine_generator_and_creator_); if (length == 0) { SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT); } else { @@ -1395,13 +1378,11 @@ } void QuicPacketCreator::SetTransmissionType(TransmissionType type) { - DCHECK(combine_generator_and_creator_); next_transmission_type_ = type; } MessageStatus QuicPacketCreator::AddMessageFrame(QuicMessageId message_id, QuicMemSliceSpan message) { - DCHECK(combine_generator_and_creator_); QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when " "generator tries to add message frame."; MaybeBundleAckOpportunistically(); @@ -1809,7 +1790,6 @@ } bool QuicPacketCreator::PacketFlusherAttached() const { - DCHECK(combine_generator_and_creator_); return flusher_attached_; }
diff --git a/quic/core/quic_packet_creator.h b/quic/core/quic_packet_creator.h index b8240c1..7460502 100644 --- a/quic/core/quic_packet_creator.h +++ b/quic/core/quic_packet_creator.h
@@ -2,8 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Accumulates frames for the next packet until more frames no longer fit or -// it's time to create a packet from them. +// Responsible for creating packets on behalf of a QuicConnection. +// Packets are serialized just-in-time. Stream data and control frames will be +// requested from the Connection just-in-time. Frames are accumulated into +// "current" packet until no more frames can fit, then current packet gets +// serialized and passed to connection via OnSerializedPacket(). +// +// Whether a packet should be serialized is determined by whether delegate is +// writable. If the Delegate is not writable, then no operations will cause +// a packet to be serialized. #ifndef QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_ #define QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_ @@ -377,19 +384,13 @@ bool PacketFlusherAttached() const; void set_fully_pad_crypto_handshake_packets(bool new_value) { - DCHECK(combine_generator_and_creator_); fully_pad_crypto_handshake_packets_ = new_value; } bool fully_pad_crypto_handshake_packets() const { - DCHECK(combine_generator_and_creator_); return fully_pad_crypto_handshake_packets_; } - bool combine_generator_and_creator() const { - return combine_generator_and_creator_; - } - // Serialize a probing packet that uses IETF QUIC's PATH CHALLENGE frame. Also // fills the packet with padding. size_t BuildPaddedPathChallengePacket(const QuicPacketHeader& header, @@ -592,9 +593,6 @@ // set to a soft value. QuicByteCount latched_hard_max_packet_length_; - // Latched value of quic_combine_generator_and_creator. - const bool combine_generator_and_creator_; - // Latched value of quic_populate_nonretransmittable_frames. const bool populate_nonretransmittable_frames_; };
diff --git a/quic/core/quic_packet_creator_test.cc b/quic/core/quic_packet_creator_test.cc index 4efcbfe..25161e1 100644 --- a/quic/core/quic_packet_creator_test.cc +++ b/quic/core/quic_packet_creator_test.cc
@@ -30,6 +30,7 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h" +#include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h" using testing::_; using testing::DoAll; @@ -2239,6 +2240,1495 @@ EXPECT_TRUE(creator_.HasPendingFrames()); } +class MockDelegate : public QuicPacketCreator::DelegateInterface { + public: + MockDelegate() {} + MockDelegate(const MockDelegate&) = delete; + MockDelegate& operator=(const MockDelegate&) = delete; + ~MockDelegate() override {} + + MOCK_METHOD2(ShouldGeneratePacket, + bool(HasRetransmittableData retransmittable, + IsHandshake handshake)); + MOCK_METHOD0(MaybeBundleAckOpportunistically, const QuicFrames()); + MOCK_METHOD0(GetPacketBuffer, char*()); + MOCK_METHOD1(OnSerializedPacket, void(SerializedPacket* packet)); + MOCK_METHOD2(OnUnrecoverableError, void(QuicErrorCode, const std::string&)); + + void SetCanWriteAnything() { + EXPECT_CALL(*this, ShouldGeneratePacket(_, _)).WillRepeatedly(Return(true)); + EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _)) + .WillRepeatedly(Return(true)); + } + + void SetCanNotWrite() { + EXPECT_CALL(*this, ShouldGeneratePacket(_, _)) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _)) + .WillRepeatedly(Return(false)); + } + + // Use this when only ack frames should be allowed to be written. + void SetCanWriteOnlyNonRetransmittable() { + EXPECT_CALL(*this, ShouldGeneratePacket(_, _)) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _)) + .WillRepeatedly(Return(true)); + } +}; + +// Simple struct for describing the contents of a packet. +// Useful in conjunction with a SimpleQuicFrame for validating that a packet +// contains the expected frames. +struct PacketContents { + PacketContents() + : num_ack_frames(0), + num_connection_close_frames(0), + num_goaway_frames(0), + num_rst_stream_frames(0), + num_stop_waiting_frames(0), + num_stream_frames(0), + num_crypto_frames(0), + num_ping_frames(0), + num_mtu_discovery_frames(0), + num_padding_frames(0) {} + + size_t num_ack_frames; + size_t num_connection_close_frames; + size_t num_goaway_frames; + size_t num_rst_stream_frames; + size_t num_stop_waiting_frames; + size_t num_stream_frames; + size_t num_crypto_frames; + size_t num_ping_frames; + size_t num_mtu_discovery_frames; + size_t num_padding_frames; +}; + +class MultiplePacketsTestPacketCreator : public QuicPacketCreator { + public: + MultiplePacketsTestPacketCreator( + QuicConnectionId connection_id, + QuicFramer* framer, + QuicRandom* random_generator, + QuicPacketCreator::DelegateInterface* delegate, + SimpleDataProducer* producer) + : QuicPacketCreator(connection_id, framer, random_generator, delegate), + ack_frame_(InitAckFrame(1)), + delegate_(static_cast<MockDelegate*>(delegate)), + producer_(producer) {} + + bool ConsumeRetransmittableControlFrame(const QuicFrame& frame, + bool bundle_ack) { + if (!has_ack()) { + QuicFrames frames; + if (bundle_ack) { + frames.push_back(QuicFrame(&ack_frame_)); + } + if (delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, + NOT_HANDSHAKE)) { + EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()) + .WillOnce(Return(frames)); + } + } + return QuicPacketCreator::ConsumeRetransmittableControlFrame(frame); + } + + QuicConsumedData ConsumeDataFastPath(QuicStreamId id, + const struct iovec* iov, + int iov_count, + size_t total_length, + QuicStreamOffset offset, + bool fin) { + // Save data before data is consumed. + if (total_length > 0) { + producer_->SaveStreamData(id, iov, iov_count, 0, total_length); + } + return QuicPacketCreator::ConsumeDataFastPath(id, total_length, offset, fin, + 0); + } + + QuicConsumedData ConsumeData(QuicStreamId id, + const struct iovec* iov, + int iov_count, + size_t total_length, + QuicStreamOffset offset, + StreamSendingState state) { + // Save data before data is consumed. + if (total_length > 0) { + producer_->SaveStreamData(id, iov, iov_count, 0, total_length); + } + if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, + NOT_HANDSHAKE)) { + EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1); + } + return QuicPacketCreator::ConsumeData(id, total_length, offset, state); + } + + MessageStatus AddMessageFrame(QuicMessageId message_id, + QuicMemSliceSpan message) { + if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, + NOT_HANDSHAKE)) { + EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1); + } + return QuicPacketCreator::AddMessageFrame(message_id, message); + } + + size_t ConsumeCryptoData(EncryptionLevel level, + QuicStringPiece data, + QuicStreamOffset offset) { + producer_->SaveCryptoData(level, offset, data); + if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, + NOT_HANDSHAKE)) { + EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1); + } + return QuicPacketCreator::ConsumeCryptoData(level, data.length(), offset); + } + + QuicAckFrame ack_frame_; + MockDelegate* delegate_; + SimpleDataProducer* producer_; +}; + +class QuicPacketCreatorMultiplePacketsTest : public QuicTest { + public: + QuicPacketCreatorMultiplePacketsTest() + : framer_(AllSupportedVersions(), + QuicTime::Zero(), + Perspective::IS_CLIENT, + kQuicDefaultConnectionIdLength), + creator_(TestConnectionId(), + &framer_, + &random_creator_, + &delegate_, + &producer_), + ack_frame_(InitAckFrame(1)) { + EXPECT_CALL(delegate_, GetPacketBuffer()).WillRepeatedly(Return(nullptr)); + creator_.SetEncrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullEncrypter>(Perspective::IS_CLIENT)); + creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE); + framer_.set_data_producer(&producer_); + if (simple_framer_.framer()->version().KnowsWhichDecrypterToUse()) { + simple_framer_.framer()->InstallDecrypter( + ENCRYPTION_FORWARD_SECURE, + std::make_unique<NullDecrypter>(Perspective::IS_SERVER)); + } + creator_.AttachPacketFlusher(); + } + + ~QuicPacketCreatorMultiplePacketsTest() override { + for (SerializedPacket& packet : packets_) { + delete[] packet.encrypted_buffer; + ClearSerializedPacket(&packet); + } + } + + void SavePacket(SerializedPacket* packet) { + packet->encrypted_buffer = CopyBuffer(*packet); + packets_.push_back(*packet); + packet->encrypted_buffer = nullptr; + packet->retransmittable_frames.clear(); + } + + protected: + QuicRstStreamFrame* CreateRstStreamFrame() { + return new QuicRstStreamFrame(1, 1, QUIC_STREAM_NO_ERROR, 0); + } + + QuicGoAwayFrame* CreateGoAwayFrame() { + return new QuicGoAwayFrame(2, QUIC_NO_ERROR, 1, std::string()); + } + + void CheckPacketContains(const PacketContents& contents, + size_t packet_index) { + ASSERT_GT(packets_.size(), packet_index); + const SerializedPacket& packet = packets_[packet_index]; + size_t num_retransmittable_frames = + contents.num_connection_close_frames + contents.num_goaway_frames + + contents.num_rst_stream_frames + contents.num_stream_frames + + contents.num_crypto_frames + contents.num_ping_frames; + size_t num_frames = + contents.num_ack_frames + contents.num_stop_waiting_frames + + contents.num_mtu_discovery_frames + contents.num_padding_frames + + num_retransmittable_frames; + + if (num_retransmittable_frames == 0) { + ASSERT_TRUE(packet.retransmittable_frames.empty()); + } else { + ASSERT_FALSE(packet.retransmittable_frames.empty()); + EXPECT_EQ(num_retransmittable_frames, + packet.retransmittable_frames.size()); + } + + ASSERT_TRUE(packet.encrypted_buffer != nullptr); + ASSERT_TRUE(simple_framer_.ProcessPacket( + QuicEncryptedPacket(packet.encrypted_buffer, packet.encrypted_length))); + size_t num_padding_frames = 0; + if (contents.num_padding_frames == 0) { + num_padding_frames = simple_framer_.padding_frames().size(); + } + EXPECT_EQ(num_frames + num_padding_frames, simple_framer_.num_frames()); + EXPECT_EQ(contents.num_ack_frames, simple_framer_.ack_frames().size()); + EXPECT_EQ(contents.num_connection_close_frames, + simple_framer_.connection_close_frames().size()); + EXPECT_EQ(contents.num_goaway_frames, + simple_framer_.goaway_frames().size()); + EXPECT_EQ(contents.num_rst_stream_frames, + simple_framer_.rst_stream_frames().size()); + EXPECT_EQ(contents.num_stream_frames, + simple_framer_.stream_frames().size()); + EXPECT_EQ(contents.num_crypto_frames, + simple_framer_.crypto_frames().size()); + EXPECT_EQ(contents.num_stop_waiting_frames, + simple_framer_.stop_waiting_frames().size()); + if (contents.num_padding_frames != 0) { + EXPECT_EQ(contents.num_padding_frames, + simple_framer_.padding_frames().size()); + } + + // From the receiver's perspective, MTU discovery frames are ping frames. + EXPECT_EQ(contents.num_ping_frames + contents.num_mtu_discovery_frames, + simple_framer_.ping_frames().size()); + } + + void CheckPacketHasSingleStreamFrame(size_t packet_index) { + ASSERT_GT(packets_.size(), packet_index); + const SerializedPacket& packet = packets_[packet_index]; + ASSERT_FALSE(packet.retransmittable_frames.empty()); + EXPECT_EQ(1u, packet.retransmittable_frames.size()); + ASSERT_TRUE(packet.encrypted_buffer != nullptr); + ASSERT_TRUE(simple_framer_.ProcessPacket( + QuicEncryptedPacket(packet.encrypted_buffer, packet.encrypted_length))); + EXPECT_EQ(1u, simple_framer_.num_frames()); + EXPECT_EQ(1u, simple_framer_.stream_frames().size()); + } + + void CheckAllPacketsHaveSingleStreamFrame() { + for (size_t i = 0; i < packets_.size(); i++) { + CheckPacketHasSingleStreamFrame(i); + } + } + + void CreateData(size_t len) { + data_array_.reset(new char[len]); + memset(data_array_.get(), '?', len); + iov_.iov_base = data_array_.get(); + iov_.iov_len = len; + } + + QuicFramer framer_; + MockRandom random_creator_; + StrictMock<MockDelegate> delegate_; + MultiplePacketsTestPacketCreator creator_; + SimpleQuicFramer simple_framer_; + std::vector<SerializedPacket> packets_; + QuicAckFrame ack_frame_; + struct iovec iov_; + SimpleBufferAllocator allocator_; + + private: + std::unique_ptr<char[]> data_array_; + SimpleDataProducer producer_; +}; + +TEST_F(QuicPacketCreatorMultiplePacketsTest, AddControlFrame_NotWritable) { + delegate_.SetCanNotWrite(); + + QuicRstStreamFrame* rst_frame = CreateRstStreamFrame(); + const bool consumed = + creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), + /*bundle_ack=*/false); + EXPECT_FALSE(consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + delete rst_frame; +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, AddControlFrame_OnlyAckWritable) { + delegate_.SetCanWriteOnlyNonRetransmittable(); + + QuicRstStreamFrame* rst_frame = CreateRstStreamFrame(); + const bool consumed = + creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), + /*bundle_ack=*/false); + EXPECT_FALSE(consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + delete rst_frame; +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, + AddControlFrame_WritableAndShouldNotFlush) { + delegate_.SetCanWriteAnything(); + + creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateRstStreamFrame()), + /*bundle_ack=*/false); + EXPECT_TRUE(creator_.HasPendingFrames()); + EXPECT_TRUE(creator_.HasPendingRetransmittableFrames()); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, + AddControlFrame_NotWritableBatchThenFlush) { + delegate_.SetCanNotWrite(); + + QuicRstStreamFrame* rst_frame = CreateRstStreamFrame(); + const bool consumed = + creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), + /*bundle_ack=*/false); + EXPECT_FALSE(consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + delete rst_frame; +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, + AddControlFrame_WritableAndShouldFlush) { + delegate_.SetCanWriteAnything(); + + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + + creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateRstStreamFrame()), + /*bundle_ack=*/false); + creator_.Flush(); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + PacketContents contents; + contents.num_rst_stream_frames = 1; + CheckPacketContains(contents, 0); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeCryptoData) { + delegate_.SetCanWriteAnything(); + + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + std::string data = "crypto data"; + size_t consumed_bytes = + creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0); + creator_.Flush(); + EXPECT_EQ(data.length(), consumed_bytes); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + PacketContents contents; + contents.num_crypto_frames = 1; + contents.num_padding_frames = 1; + CheckPacketContains(contents, 0); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_NotWritable) { + delegate_.SetCanNotWrite(); + + MakeIOVector("foo", &iov_); + QuicConsumedData consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, 0, FIN); + EXPECT_EQ(0u, consumed.bytes_consumed); + EXPECT_FALSE(consumed.fin_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, + ConsumeData_WritableAndShouldNotFlush) { + delegate_.SetCanWriteAnything(); + + MakeIOVector("foo", &iov_); + QuicConsumedData consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, 0, FIN); + EXPECT_EQ(3u, consumed.bytes_consumed); + EXPECT_TRUE(consumed.fin_consumed); + EXPECT_TRUE(creator_.HasPendingFrames()); + EXPECT_TRUE(creator_.HasPendingRetransmittableFrames()); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, + ConsumeData_WritableAndShouldFlush) { + delegate_.SetCanWriteAnything(); + + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + MakeIOVector("foo", &iov_); + QuicConsumedData consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, 0, FIN); + creator_.Flush(); + EXPECT_EQ(3u, consumed.bytes_consumed); + EXPECT_TRUE(consumed.fin_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + PacketContents contents; + contents.num_stream_frames = 1; + CheckPacketContains(contents, 0); +} + +// Test the behavior of ConsumeData when the data consumed is for the crypto +// handshake stream. Ensure that the packet is always sent and padded even if +// the creator operates in batch mode. +TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_Handshake) { + delegate_.SetCanWriteAnything(); + + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + std::string data = "foo bar"; + MakeIOVector(data, &iov_); + size_t consumed_bytes = 0; + if (QuicVersionUsesCryptoFrames(framer_.transport_version())) { + consumed_bytes = creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0); + } else { + consumed_bytes = + creator_ + .ConsumeData( + QuicUtils::GetCryptoStreamId(framer_.transport_version()), + &iov_, 1u, iov_.iov_len, 0, NO_FIN) + .bytes_consumed; + } + EXPECT_EQ(7u, consumed_bytes); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + PacketContents contents; + if (QuicVersionUsesCryptoFrames(framer_.transport_version())) { + contents.num_crypto_frames = 1; + } else { + contents.num_stream_frames = 1; + } + contents.num_padding_frames = 1; + CheckPacketContains(contents, 0); + + ASSERT_EQ(1u, packets_.size()); + ASSERT_EQ(kDefaultMaxPacketSize, creator_.max_packet_length()); + EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length); +} + +// Test the behavior of ConsumeData when the data is for the crypto handshake +// stream, but padding is disabled. +TEST_F(QuicPacketCreatorMultiplePacketsTest, + ConsumeData_Handshake_PaddingDisabled) { + creator_.set_fully_pad_crypto_handshake_packets(false); + + delegate_.SetCanWriteAnything(); + + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + std::string data = "foo"; + MakeIOVector(data, &iov_); + size_t bytes_consumed = 0; + if (QuicVersionUsesCryptoFrames(framer_.transport_version())) { + bytes_consumed = creator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0); + } else { + bytes_consumed = + creator_ + .ConsumeData( + QuicUtils::GetCryptoStreamId(framer_.transport_version()), + &iov_, 1u, iov_.iov_len, 0, NO_FIN) + .bytes_consumed; + } + EXPECT_EQ(3u, bytes_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + PacketContents contents; + if (QuicVersionUsesCryptoFrames(framer_.transport_version())) { + contents.num_crypto_frames = 1; + } else { + contents.num_stream_frames = 1; + } + contents.num_padding_frames = 0; + CheckPacketContains(contents, 0); + + ASSERT_EQ(1u, packets_.size()); + + // Packet is not fully padded, but we want to future packets to be larger. + ASSERT_EQ(kDefaultMaxPacketSize, creator_.max_packet_length()); + size_t expected_packet_length = 27; + if (QuicVersionUsesCryptoFrames(framer_.transport_version())) { + // The framing of CRYPTO frames is slightly different than that of stream + // frames, so the expected packet length differs slightly. + expected_packet_length = 28; + } + if (framer_.version().HasHeaderProtection()) { + expected_packet_length = 29; + } + EXPECT_EQ(expected_packet_length, packets_[0].encrypted_length); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_EmptyData) { + delegate_.SetCanWriteAnything(); + + EXPECT_QUIC_BUG(creator_.ConsumeData( + QuicUtils::QuicUtils::GetFirstBidirectionalStreamId( + framer_.transport_version(), Perspective::IS_CLIENT), + nullptr, 0, 0, 0, NO_FIN), + "Attempt to consume empty data without FIN."); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, + ConsumeDataMultipleTimes_WritableAndShouldNotFlush) { + delegate_.SetCanWriteAnything(); + + MakeIOVector("foo", &iov_); + creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId( + framer_.transport_version(), Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, 0, FIN); + MakeIOVector("quux", &iov_); + QuicConsumedData consumed = + creator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 3, NO_FIN); + EXPECT_EQ(4u, consumed.bytes_consumed); + EXPECT_FALSE(consumed.fin_consumed); + EXPECT_TRUE(creator_.HasPendingFrames()); + EXPECT_TRUE(creator_.HasPendingRetransmittableFrames()); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeData_BatchOperations) { + delegate_.SetCanWriteAnything(); + + MakeIOVector("foo", &iov_); + creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId( + framer_.transport_version(), Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, 0, NO_FIN); + MakeIOVector("quux", &iov_); + QuicConsumedData consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, 3, FIN); + EXPECT_EQ(4u, consumed.bytes_consumed); + EXPECT_TRUE(consumed.fin_consumed); + EXPECT_TRUE(creator_.HasPendingFrames()); + EXPECT_TRUE(creator_.HasPendingRetransmittableFrames()); + + // Now both frames will be flushed out. + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + creator_.Flush(); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + PacketContents contents; + contents.num_stream_frames = + GetQuicReloadableFlag(quic_coalesce_stream_frames) ? 1 : 2; + CheckPacketContains(contents, 0); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, + ConsumeData_FramesPreviouslyQueued) { + // Set the packet size be enough for two stream frames with 0 stream offset, + // but not enough for a stream frame of 0 offset and one with non-zero offset. + size_t length = + NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) + + GetPacketHeaderSize( + framer_.transport_version(), + creator_.GetDestinationConnectionIdLength(), + creator_.GetSourceConnectionIdLength(), + QuicPacketCreatorPeer::SendVersionInPacket(&creator_), + !kIncludeDiversificationNonce, + QuicPacketCreatorPeer::GetPacketNumberLength(&creator_), + QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0, + QuicPacketCreatorPeer::GetLengthLength(&creator_)) + + // Add an extra 3 bytes for the payload and 1 byte so + // BytesFree is larger than the GetMinStreamFrameSize. + QuicFramer::GetMinStreamFrameSize(framer_.transport_version(), 1, 0, + false, 3) + + 3 + + QuicFramer::GetMinStreamFrameSize(framer_.transport_version(), 1, 0, true, + 1) + + 1; + creator_.SetMaxPacketLength(length); + delegate_.SetCanWriteAnything(); + { + InSequence dummy; + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + } + // Queue enough data to prevent a stream frame with a non-zero offset from + // fitting. + MakeIOVector("foo", &iov_); + QuicConsumedData consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, 0, NO_FIN); + EXPECT_EQ(3u, consumed.bytes_consumed); + EXPECT_FALSE(consumed.fin_consumed); + EXPECT_TRUE(creator_.HasPendingFrames()); + EXPECT_TRUE(creator_.HasPendingRetransmittableFrames()); + + // This frame will not fit with the existing frame, causing the queued frame + // to be serialized, and it will be added to a new open packet. + MakeIOVector("bar", &iov_); + consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, 3, FIN); + EXPECT_EQ(3u, consumed.bytes_consumed); + EXPECT_TRUE(consumed.fin_consumed); + EXPECT_TRUE(creator_.HasPendingFrames()); + EXPECT_TRUE(creator_.HasPendingRetransmittableFrames()); + + creator_.FlushCurrentPacket(); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + PacketContents contents; + contents.num_stream_frames = 1; + CheckPacketContains(contents, 0); + CheckPacketContains(contents, 1); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataFastPath) { + delegate_.SetCanWriteAnything(); + creator_.SetTransmissionType(LOSS_RETRANSMISSION); + + // Create a 10000 byte IOVector. + CreateData(10000); + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillRepeatedly( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + QuicConsumedData consumed = creator_.ConsumeDataFastPath( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, 0, true); + EXPECT_EQ(10000u, consumed.bytes_consumed); + EXPECT_TRUE(consumed.fin_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + PacketContents contents; + contents.num_stream_frames = 1; + CheckPacketContains(contents, 0); + EXPECT_FALSE(packets_.empty()); + SerializedPacket packet = packets_.back(); + EXPECT_TRUE(!packet.retransmittable_frames.empty()); + EXPECT_EQ(LOSS_RETRANSMISSION, packet.transmission_type); + EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type); + const QuicStreamFrame& stream_frame = + packet.retransmittable_frames.front().stream_frame; + EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataLarge) { + delegate_.SetCanWriteAnything(); + + // Create a 10000 byte IOVector. + CreateData(10000); + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillRepeatedly( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + QuicConsumedData consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, 0, FIN); + EXPECT_EQ(10000u, consumed.bytes_consumed); + EXPECT_TRUE(consumed.fin_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + PacketContents contents; + contents.num_stream_frames = 1; + CheckPacketContains(contents, 0); + EXPECT_FALSE(packets_.empty()); + SerializedPacket packet = packets_.back(); + EXPECT_TRUE(!packet.retransmittable_frames.empty()); + EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type); + const QuicStreamFrame& stream_frame = + packet.retransmittable_frames.front().stream_frame; + EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataLargeSendAckFalse) { + delegate_.SetCanNotWrite(); + + QuicRstStreamFrame* rst_frame = CreateRstStreamFrame(); + const bool success = + creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), + /*bundle_ack=*/true); + EXPECT_FALSE(success); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + delegate_.SetCanWriteAnything(); + + creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), + /*bundle_ack=*/false); + + // Create a 10000 byte IOVector. + CreateData(10000); + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillRepeatedly( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateRstStreamFrame()), + /*bundle_ack=*/true); + QuicConsumedData consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, 0, FIN); + creator_.Flush(); + + EXPECT_EQ(10000u, consumed.bytes_consumed); + EXPECT_TRUE(consumed.fin_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + EXPECT_FALSE(packets_.empty()); + SerializedPacket packet = packets_.back(); + EXPECT_TRUE(!packet.retransmittable_frames.empty()); + EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type); + const QuicStreamFrame& stream_frame = + packet.retransmittable_frames.front().stream_frame; + EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, ConsumeDataLargeSendAckTrue) { + if (VersionHasIetfInvariantHeader(framer_.transport_version())) { + return; + } + delegate_.SetCanNotWrite(); + delegate_.SetCanWriteAnything(); + + // Create a 10000 byte IOVector. + CreateData(10000); + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillRepeatedly( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + QuicConsumedData consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, 0, FIN); + creator_.Flush(); + + EXPECT_EQ(10000u, consumed.bytes_consumed); + EXPECT_TRUE(consumed.fin_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + EXPECT_FALSE(packets_.empty()); + SerializedPacket packet = packets_.back(); + EXPECT_TRUE(!packet.retransmittable_frames.empty()); + EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type); + const QuicStreamFrame& stream_frame = + packet.retransmittable_frames.front().stream_frame; + EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, NotWritableThenBatchOperations) { + delegate_.SetCanNotWrite(); + + QuicRstStreamFrame* rst_frame = CreateRstStreamFrame(); + const bool consumed = + creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), + /*bundle_ack=*/true); + EXPECT_FALSE(consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(3)); + + delegate_.SetCanWriteAnything(); + + EXPECT_TRUE( + creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), + /*bundle_ack=*/false)); + // Send some data and a control frame + MakeIOVector("quux", &iov_); + creator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 0, NO_FIN); + if (!VersionHasIetfQuicFrames(framer_.transport_version())) { + creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateGoAwayFrame()), + /*bundle_ack=*/false); + } + EXPECT_TRUE(creator_.HasPendingStreamFramesOfStream(3)); + + // All five frames will be flushed out in a single packet. + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + creator_.Flush(); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + EXPECT_FALSE(creator_.HasPendingStreamFramesOfStream(3)); + + PacketContents contents; + // ACK will be flushed by connection. + contents.num_ack_frames = 0; + if (!VersionHasIetfQuicFrames(framer_.transport_version())) { + contents.num_goaway_frames = 1; + } else { + contents.num_goaway_frames = 0; + } + contents.num_rst_stream_frames = 1; + contents.num_stream_frames = 1; + CheckPacketContains(contents, 0); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, NotWritableThenBatchOperations2) { + delegate_.SetCanNotWrite(); + + QuicRstStreamFrame* rst_frame = CreateRstStreamFrame(); + const bool success = + creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), + /*bundle_ack=*/true); + EXPECT_FALSE(success); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + delegate_.SetCanWriteAnything(); + + { + InSequence dummy; + // All five frames will be flushed out in a single packet + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + } + EXPECT_TRUE( + creator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), + /*bundle_ack=*/false)); + // Send enough data to exceed one packet + size_t data_len = kDefaultMaxPacketSize + 100; + CreateData(data_len); + QuicConsumedData consumed = + creator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 0, FIN); + EXPECT_EQ(data_len, consumed.bytes_consumed); + EXPECT_TRUE(consumed.fin_consumed); + if (!VersionHasIetfQuicFrames(framer_.transport_version())) { + creator_.ConsumeRetransmittableControlFrame(QuicFrame(CreateGoAwayFrame()), + /*bundle_ack=*/false); + } + + creator_.Flush(); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + // The first packet should have the queued data and part of the stream data. + PacketContents contents; + // ACK will be sent by connection. + contents.num_ack_frames = 0; + contents.num_rst_stream_frames = 1; + contents.num_stream_frames = 1; + CheckPacketContains(contents, 0); + + // The second should have the remainder of the stream data. + PacketContents contents2; + if (!VersionHasIetfQuicFrames(framer_.transport_version())) { + contents2.num_goaway_frames = 1; + } else { + contents2.num_goaway_frames = 0; + } + contents2.num_stream_frames = 1; + CheckPacketContains(contents2, 1); +} + +// Regression test of b/120493795. +TEST_F(QuicPacketCreatorMultiplePacketsTest, PacketTransmissionType) { + delegate_.SetCanWriteAnything(); + + // The first ConsumeData will fill the packet without flush. + creator_.SetTransmissionType(LOSS_RETRANSMISSION); + + size_t data_len = 1324; + CreateData(data_len); + QuicStreamId stream1_id = QuicUtils::GetFirstBidirectionalStreamId( + framer_.transport_version(), Perspective::IS_CLIENT); + QuicConsumedData consumed = + creator_.ConsumeData(stream1_id, &iov_, 1u, iov_.iov_len, 0, NO_FIN); + EXPECT_EQ(data_len, consumed.bytes_consumed); + ASSERT_EQ(0u, creator_.BytesFree()) + << "Test setup failed: Please increase data_len to " + << data_len + creator_.BytesFree() << " bytes."; + + // The second ConsumeData can not be added to the packet and will flush. + creator_.SetTransmissionType(NOT_RETRANSMISSION); + + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + + QuicStreamId stream2_id = stream1_id + 4; + + consumed = + creator_.ConsumeData(stream2_id, &iov_, 1u, iov_.iov_len, 0, NO_FIN); + EXPECT_EQ(data_len, consumed.bytes_consumed); + + // Ensure the packet is successfully created. + ASSERT_EQ(1u, packets_.size()); + ASSERT_TRUE(packets_[0].encrypted_buffer); + ASSERT_EQ(1u, packets_[0].retransmittable_frames.size()); + EXPECT_EQ(stream1_id, + packets_[0].retransmittable_frames[0].stream_frame.stream_id); + + // Since the second frame was not added, the packet's transmission type + // should be the first frame's type. + EXPECT_EQ(packets_[0].transmission_type, LOSS_RETRANSMISSION); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, TestConnectionIdLength) { + QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); + creator_.SetServerConnectionIdLength(0); + EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID, + creator_.GetDestinationConnectionIdLength()); + + for (size_t i = 1; i < 10; i++) { + creator_.SetServerConnectionIdLength(i); + if (VersionHasIetfInvariantHeader(framer_.transport_version())) { + EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID, + creator_.GetDestinationConnectionIdLength()); + } else { + EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID, + creator_.GetDestinationConnectionIdLength()); + } + } +} + +// Test whether SetMaxPacketLength() works in the situation when the queue is +// empty, and we send three packets worth of data. +TEST_F(QuicPacketCreatorMultiplePacketsTest, SetMaxPacketLength_Initial) { + delegate_.SetCanWriteAnything(); + + // Send enough data for three packets. + size_t data_len = 3 * kDefaultMaxPacketSize + 1; + size_t packet_len = kDefaultMaxPacketSize + 100; + ASSERT_LE(packet_len, kMaxOutgoingPacketSize); + creator_.SetMaxPacketLength(packet_len); + EXPECT_EQ(packet_len, creator_.max_packet_length()); + + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .Times(3) + .WillRepeatedly( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + CreateData(data_len); + QuicConsumedData consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, + /*offset=*/0, FIN); + EXPECT_EQ(data_len, consumed.bytes_consumed); + EXPECT_TRUE(consumed.fin_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + // We expect three packets, and first two of them have to be of packet_len + // size. We check multiple packets (instead of just one) because we want to + // ensure that |max_packet_length_| does not get changed incorrectly by the + // creator after first packet is serialized. + ASSERT_EQ(3u, packets_.size()); + EXPECT_EQ(packet_len, packets_[0].encrypted_length); + EXPECT_EQ(packet_len, packets_[1].encrypted_length); + CheckAllPacketsHaveSingleStreamFrame(); +} + +// Test whether SetMaxPacketLength() works in the situation when we first write +// data, then change packet size, then write data again. +TEST_F(QuicPacketCreatorMultiplePacketsTest, SetMaxPacketLength_Middle) { + delegate_.SetCanWriteAnything(); + + // We send enough data to overflow default packet length, but not the altered + // one. + size_t data_len = kDefaultMaxPacketSize; + size_t packet_len = kDefaultMaxPacketSize + 100; + ASSERT_LE(packet_len, kMaxOutgoingPacketSize); + + // We expect to see three packets in total. + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .Times(3) + .WillRepeatedly( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + + // Send two packets before packet size change. + CreateData(data_len); + QuicConsumedData consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, + /*offset=*/0, NO_FIN); + creator_.Flush(); + EXPECT_EQ(data_len, consumed.bytes_consumed); + EXPECT_FALSE(consumed.fin_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + // Make sure we already have two packets. + ASSERT_EQ(2u, packets_.size()); + + // Increase packet size. + creator_.SetMaxPacketLength(packet_len); + EXPECT_EQ(packet_len, creator_.max_packet_length()); + + // Send a packet after packet size change. + CreateData(data_len); + creator_.AttachPacketFlusher(); + consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, data_len, FIN); + creator_.Flush(); + EXPECT_EQ(data_len, consumed.bytes_consumed); + EXPECT_TRUE(consumed.fin_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + // We expect first data chunk to get fragmented, but the second one to fit + // into a single packet. + ASSERT_EQ(3u, packets_.size()); + EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length); + EXPECT_LE(kDefaultMaxPacketSize, packets_[2].encrypted_length); + CheckAllPacketsHaveSingleStreamFrame(); +} + +// Test whether SetMaxPacketLength() works correctly when we force the change of +// the packet size in the middle of the batched packet. +TEST_F(QuicPacketCreatorMultiplePacketsTest, + SetMaxPacketLength_MidpacketFlush) { + delegate_.SetCanWriteAnything(); + + size_t first_write_len = kDefaultMaxPacketSize / 2; + size_t packet_len = kDefaultMaxPacketSize + 100; + size_t second_write_len = packet_len + 1; + ASSERT_LE(packet_len, kMaxOutgoingPacketSize); + + // First send half of the packet worth of data. We are in the batch mode, so + // should not cause packet serialization. + CreateData(first_write_len); + QuicConsumedData consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, + /*offset=*/0, NO_FIN); + EXPECT_EQ(first_write_len, consumed.bytes_consumed); + EXPECT_FALSE(consumed.fin_consumed); + EXPECT_TRUE(creator_.HasPendingFrames()); + EXPECT_TRUE(creator_.HasPendingRetransmittableFrames()); + + // Make sure we have no packets so far. + ASSERT_EQ(0u, packets_.size()); + + // Expect a packet to be flushed. + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + + // Increase packet size after flushing all frames. + // Ensure it's immediately enacted. + creator_.FlushCurrentPacket(); + creator_.SetMaxPacketLength(packet_len); + EXPECT_EQ(packet_len, creator_.max_packet_length()); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + // We expect to see exactly one packet serialized after that, because we send + // a value somewhat exceeding new max packet size, and the tail data does not + // get serialized because we are still in the batch mode. + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + + // Send a more than a packet worth of data to the same stream. This should + // trigger serialization of one packet, and queue another one. + CreateData(second_write_len); + consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, + /*offset=*/first_write_len, FIN); + EXPECT_EQ(second_write_len, consumed.bytes_consumed); + EXPECT_TRUE(consumed.fin_consumed); + EXPECT_TRUE(creator_.HasPendingFrames()); + EXPECT_TRUE(creator_.HasPendingRetransmittableFrames()); + + // We expect the first packet to be underfilled, and the second packet be up + // to the new max packet size. + ASSERT_EQ(2u, packets_.size()); + EXPECT_GT(kDefaultMaxPacketSize, packets_[0].encrypted_length); + EXPECT_EQ(packet_len, packets_[1].encrypted_length); + + CheckAllPacketsHaveSingleStreamFrame(); +} + +// Test sending a connectivity probing packet. +TEST_F(QuicPacketCreatorMultiplePacketsTest, + GenerateConnectivityProbingPacket) { + delegate_.SetCanWriteAnything(); + + OwningSerializedPacketPointer probing_packet; + if (VersionHasIetfQuicFrames(framer_.transport_version())) { + QuicPathFrameBuffer payload = { + {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}}; + probing_packet = + creator_.SerializePathChallengeConnectivityProbingPacket(&payload); + } else { + probing_packet = creator_.SerializeConnectivityProbingPacket(); + } + + ASSERT_TRUE(simple_framer_.ProcessPacket(QuicEncryptedPacket( + probing_packet->encrypted_buffer, probing_packet->encrypted_length))); + + EXPECT_EQ(2u, simple_framer_.num_frames()); + if (VersionHasIetfQuicFrames(framer_.transport_version())) { + EXPECT_EQ(1u, simple_framer_.path_challenge_frames().size()); + } else { + EXPECT_EQ(1u, simple_framer_.ping_frames().size()); + } + EXPECT_EQ(1u, simple_framer_.padding_frames().size()); +} + +// Test sending an MTU probe, without any surrounding data. +TEST_F(QuicPacketCreatorMultiplePacketsTest, + GenerateMtuDiscoveryPacket_Simple) { + delegate_.SetCanWriteAnything(); + + const size_t target_mtu = kDefaultMaxPacketSize + 100; + static_assert(target_mtu < kMaxOutgoingPacketSize, + "The MTU probe used by the test exceeds maximum packet size"); + + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + + creator_.GenerateMtuDiscoveryPacket(target_mtu); + + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + ASSERT_EQ(1u, packets_.size()); + EXPECT_EQ(target_mtu, packets_[0].encrypted_length); + + PacketContents contents; + contents.num_mtu_discovery_frames = 1; + contents.num_padding_frames = 1; + CheckPacketContains(contents, 0); +} + +// Test sending an MTU probe. Surround it with data, to ensure that it resets +// the MTU to the value before the probe was sent. +TEST_F(QuicPacketCreatorMultiplePacketsTest, + GenerateMtuDiscoveryPacket_SurroundedByData) { + delegate_.SetCanWriteAnything(); + + const size_t target_mtu = kDefaultMaxPacketSize + 100; + static_assert(target_mtu < kMaxOutgoingPacketSize, + "The MTU probe used by the test exceeds maximum packet size"); + + // Send enough data so it would always cause two packets to be sent. + const size_t data_len = target_mtu + 1; + + // Send a total of five packets: two packets before the probe, the probe + // itself, and two packets after the probe. + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .Times(5) + .WillRepeatedly( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + + // Send data before the MTU probe. + CreateData(data_len); + QuicConsumedData consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, + /*offset=*/0, NO_FIN); + creator_.Flush(); + EXPECT_EQ(data_len, consumed.bytes_consumed); + EXPECT_FALSE(consumed.fin_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + // Send the MTU probe. + creator_.GenerateMtuDiscoveryPacket(target_mtu); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + // Send data after the MTU probe. + CreateData(data_len); + creator_.AttachPacketFlusher(); + consumed = creator_.ConsumeData( + QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), + Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, + /*offset=*/data_len, FIN); + creator_.Flush(); + EXPECT_EQ(data_len, consumed.bytes_consumed); + EXPECT_TRUE(consumed.fin_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + ASSERT_EQ(5u, packets_.size()); + EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length); + EXPECT_EQ(target_mtu, packets_[2].encrypted_length); + EXPECT_EQ(kDefaultMaxPacketSize, packets_[3].encrypted_length); + + PacketContents probe_contents; + probe_contents.num_mtu_discovery_frames = 1; + probe_contents.num_padding_frames = 1; + + CheckPacketHasSingleStreamFrame(0); + CheckPacketHasSingleStreamFrame(1); + CheckPacketContains(probe_contents, 2); + CheckPacketHasSingleStreamFrame(3); + CheckPacketHasSingleStreamFrame(4); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, DontCrashOnInvalidStopWaiting) { + if (VersionSupportsMessageFrames(framer_.transport_version())) { + return; + } + // Test added to ensure the creator does not crash when an invalid frame is + // added. Because this is an indication of internal programming errors, + // DFATALs are expected. + // A 1 byte packet number length can't encode a gap of 1000. + QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1000); + + delegate_.SetCanNotWrite(); + delegate_.SetCanWriteAnything(); + + // This will not serialize any packets, because of the invalid frame. + EXPECT_CALL(delegate_, + OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET, _)); + EXPECT_QUIC_BUG(creator_.Flush(), + "packet_number_length 1 is too small " + "for least_unacked_delta: 1001"); +} + +// Regression test for b/31486443. +TEST_F(QuicPacketCreatorMultiplePacketsTest, + ConnectionCloseFrameLargerThanPacketSize) { + delegate_.SetCanWriteAnything(); + char buf[2000] = {}; + QuicStringPiece error_details(buf, 2000); + const QuicErrorCode kQuicErrorCode = QUIC_PACKET_WRITE_ERROR; + + QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame( + framer_.transport_version(), kQuicErrorCode, std::string(error_details), + /*transport_close_frame_type=*/0); + creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame), + /*bundle_ack=*/false); + EXPECT_TRUE(creator_.HasPendingFrames()); + EXPECT_TRUE(creator_.HasPendingRetransmittableFrames()); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, + RandomPaddingAfterFinSingleStreamSinglePacket) { + const QuicByteCount kStreamFramePayloadSize = 100u; + char buf[kStreamFramePayloadSize] = {}; + const QuicStreamId kDataStreamId = 5; + // Set the packet size be enough for one stream frame with 0 stream offset and + // max size of random padding. + size_t length = + NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) + + GetPacketHeaderSize( + framer_.transport_version(), + creator_.GetDestinationConnectionIdLength(), + creator_.GetSourceConnectionIdLength(), + QuicPacketCreatorPeer::SendVersionInPacket(&creator_), + !kIncludeDiversificationNonce, + QuicPacketCreatorPeer::GetPacketNumberLength(&creator_), + QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0, + QuicPacketCreatorPeer::GetLengthLength(&creator_)) + + QuicFramer::GetMinStreamFrameSize( + framer_.transport_version(), kDataStreamId, 0, + /*last_frame_in_packet=*/false, + kStreamFramePayloadSize + kMaxNumRandomPaddingBytes) + + kStreamFramePayloadSize + kMaxNumRandomPaddingBytes; + creator_.SetMaxPacketLength(length); + delegate_.SetCanWriteAnything(); + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_); + QuicConsumedData consumed = creator_.ConsumeData( + kDataStreamId, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING); + creator_.Flush(); + EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + EXPECT_EQ(1u, packets_.size()); + PacketContents contents; + // The packet has both stream and padding frames. + contents.num_padding_frames = 1; + contents.num_stream_frames = 1; + CheckPacketContains(contents, 0); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, + RandomPaddingAfterFinSingleStreamMultiplePackets) { + const QuicByteCount kStreamFramePayloadSize = 100u; + char buf[kStreamFramePayloadSize] = {}; + const QuicStreamId kDataStreamId = 5; + // Set the packet size be enough for one stream frame with 0 stream offset + + // 1. One or more packets will accommodate. + size_t length = + NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) + + GetPacketHeaderSize( + framer_.transport_version(), + creator_.GetDestinationConnectionIdLength(), + creator_.GetSourceConnectionIdLength(), + QuicPacketCreatorPeer::SendVersionInPacket(&creator_), + !kIncludeDiversificationNonce, + QuicPacketCreatorPeer::GetPacketNumberLength(&creator_), + QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0, + QuicPacketCreatorPeer::GetLengthLength(&creator_)) + + QuicFramer::GetMinStreamFrameSize( + framer_.transport_version(), kDataStreamId, 0, + /*last_frame_in_packet=*/false, kStreamFramePayloadSize + 1) + + kStreamFramePayloadSize + 1; + creator_.SetMaxPacketLength(length); + delegate_.SetCanWriteAnything(); + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillRepeatedly( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_); + QuicConsumedData consumed = creator_.ConsumeData( + kDataStreamId, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING); + creator_.Flush(); + EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + EXPECT_LE(1u, packets_.size()); + PacketContents contents; + // The first packet has both stream and padding frames. + contents.num_stream_frames = 1; + contents.num_padding_frames = 1; + CheckPacketContains(contents, 0); + + for (size_t i = 1; i < packets_.size(); ++i) { + // Following packets only have paddings. + contents.num_stream_frames = 0; + contents.num_padding_frames = 1; + CheckPacketContains(contents, i); + } +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, + RandomPaddingAfterFinMultipleStreamsMultiplePackets) { + const QuicByteCount kStreamFramePayloadSize = 100u; + char buf[kStreamFramePayloadSize] = {}; + const QuicStreamId kDataStreamId1 = 5; + const QuicStreamId kDataStreamId2 = 6; + // Set the packet size be enough for first frame with 0 stream offset + second + // frame + 1 byte payload. two or more packets will accommodate. + size_t length = + NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) + + GetPacketHeaderSize( + framer_.transport_version(), + creator_.GetDestinationConnectionIdLength(), + creator_.GetSourceConnectionIdLength(), + QuicPacketCreatorPeer::SendVersionInPacket(&creator_), + !kIncludeDiversificationNonce, + QuicPacketCreatorPeer::GetPacketNumberLength(&creator_), + QuicPacketCreatorPeer::GetRetryTokenLengthLength(&creator_), 0, + QuicPacketCreatorPeer::GetLengthLength(&creator_)) + + QuicFramer::GetMinStreamFrameSize( + framer_.transport_version(), kDataStreamId1, 0, + /*last_frame_in_packet=*/false, kStreamFramePayloadSize) + + kStreamFramePayloadSize + + QuicFramer::GetMinStreamFrameSize(framer_.transport_version(), + kDataStreamId1, 0, + /*last_frame_in_packet=*/false, 1) + + 1; + creator_.SetMaxPacketLength(length); + delegate_.SetCanWriteAnything(); + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillRepeatedly( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_); + QuicConsumedData consumed = creator_.ConsumeData( + kDataStreamId1, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING); + EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); + MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_); + consumed = creator_.ConsumeData(kDataStreamId2, &iov_, 1u, iov_.iov_len, 0, + FIN_AND_PADDING); + EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); + creator_.Flush(); + EXPECT_FALSE(creator_.HasPendingFrames()); + EXPECT_FALSE(creator_.HasPendingRetransmittableFrames()); + + EXPECT_LE(2u, packets_.size()); + PacketContents contents; + // The first packet has two stream frames. + contents.num_stream_frames = 2; + CheckPacketContains(contents, 0); + + // The second packet has one stream frame and padding frames. + contents.num_stream_frames = 1; + contents.num_padding_frames = 1; + CheckPacketContains(contents, 1); + + for (size_t i = 2; i < packets_.size(); ++i) { + // Following packets only have paddings. + contents.num_stream_frames = 0; + contents.num_padding_frames = 1; + CheckPacketContains(contents, i); + } +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, AddMessageFrame) { + if (!VersionSupportsMessageFrames(framer_.transport_version())) { + return; + } + quic::QuicMemSliceStorage storage(nullptr, 0, nullptr, 0); + delegate_.SetCanWriteAnything(); + EXPECT_CALL(delegate_, OnSerializedPacket(_)) + .WillOnce( + Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket)); + + MakeIOVector("foo", &iov_); + creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId( + framer_.transport_version(), Perspective::IS_CLIENT), + &iov_, 1u, iov_.iov_len, 0, FIN); + EXPECT_EQ( + MESSAGE_STATUS_SUCCESS, + creator_.AddMessageFrame(1, MakeSpan(&allocator_, "message", &storage))); + EXPECT_TRUE(creator_.HasPendingFrames()); + EXPECT_TRUE(creator_.HasPendingRetransmittableFrames()); + + // Add a message which causes the flush of current packet. + EXPECT_EQ( + MESSAGE_STATUS_SUCCESS, + creator_.AddMessageFrame( + 2, + MakeSpan(&allocator_, + std::string(creator_.GetCurrentLargestMessagePayload(), 'a'), + &storage))); + EXPECT_TRUE(creator_.HasPendingRetransmittableFrames()); + + // Failed to send messages which cannot fit into one packet. + EXPECT_EQ( + MESSAGE_STATUS_TOO_LARGE, + creator_.AddMessageFrame( + 3, MakeSpan(&allocator_, + std::string( + creator_.GetCurrentLargestMessagePayload() + 10, 'a'), + &storage))); +} + +TEST_F(QuicPacketCreatorMultiplePacketsTest, ConnectionId) { + creator_.SetServerConnectionId(TestConnectionId(0x1337)); + EXPECT_EQ(TestConnectionId(0x1337), creator_.GetDestinationConnectionId()); + EXPECT_EQ(EmptyQuicConnectionId(), creator_.GetSourceConnectionId()); + if (!framer_.version().SupportsClientConnectionIds()) { + return; + } + creator_.SetClientConnectionId(TestConnectionId(0x33)); + EXPECT_EQ(TestConnectionId(0x1337), creator_.GetDestinationConnectionId()); + EXPECT_EQ(TestConnectionId(0x33), creator_.GetSourceConnectionId()); +} + } // namespace } // namespace test } // namespace quic
diff --git a/quic/core/quic_packet_generator.cc b/quic/core/quic_packet_generator.cc deleted file mode 100644 index f4a5773..0000000 --- a/quic/core/quic_packet_generator.cc +++ /dev/null
@@ -1,553 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/third_party/quiche/src/quic/core/quic_packet_generator.h" - -#include <cstdint> - -#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h" -#include "net/third_party/quiche/src/quic/core/quic_connection_id.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_server_stats.h" - -namespace quic { - -QuicPacketGenerator::QuicPacketGenerator( - QuicConnectionId server_connection_id, - QuicFramer* framer, - QuicRandom* random_generator, - QuicPacketCreator::DelegateInterface* delegate) - : delegate_(delegate), - packet_creator_(server_connection_id, framer, random_generator, delegate), - next_transmission_type_(NOT_RETRANSMISSION), - flusher_attached_(false), - random_generator_(random_generator), - fully_pad_crypto_handshake_packets_(true) {} - -QuicPacketGenerator::~QuicPacketGenerator() {} - -bool QuicPacketGenerator::ConsumeRetransmittableControlFrame( - const QuicFrame& frame) { - if (packet_creator_.combine_generator_and_creator()) { - return packet_creator_.ConsumeRetransmittableControlFrame(frame); - } - QUIC_BUG_IF(IsControlFrame(frame.type) && !GetControlFrameId(frame)) - << "Adding a control frame with no control frame id: " << frame; - DCHECK(QuicUtils::IsRetransmittableFrame(frame.type)) << frame; - MaybeBundleAckOpportunistically(); - if (packet_creator_.HasPendingFrames()) { - if (packet_creator_.AddSavedFrame(frame, next_transmission_type_)) { - // There is pending frames and current frame fits. - return true; - } - } - DCHECK(!packet_creator_.HasPendingFrames()); - if (frame.type != PING_FRAME && frame.type != CONNECTION_CLOSE_FRAME && - !delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, - NOT_HANDSHAKE)) { - // Do not check congestion window for ping or connection close frames. - return false; - } - const bool success = - packet_creator_.AddSavedFrame(frame, next_transmission_type_); - DCHECK(success); - return success; -} - -size_t QuicPacketGenerator::ConsumeCryptoData(EncryptionLevel level, - size_t write_length, - QuicStreamOffset offset) { - if (packet_creator_.combine_generator_and_creator()) { - return packet_creator_.ConsumeCryptoData(level, write_length, offset); - } - QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when " - "generator tries to write crypto data."; - MaybeBundleAckOpportunistically(); - // To make reasoning about crypto frames easier, we don't combine them with - // other retransmittable frames in a single packet. - // TODO(nharper): Once we have separate packet number spaces, everything - // should be driven by encryption level, and we should stop flushing in this - // spot. - if (packet_creator_.HasPendingRetransmittableFrames()) { - packet_creator_.FlushCurrentPacket(); - } - - size_t total_bytes_consumed = 0; - - while (total_bytes_consumed < write_length) { - QuicFrame frame; - if (!packet_creator_.ConsumeCryptoDataToFillCurrentPacket( - level, write_length - total_bytes_consumed, - offset + total_bytes_consumed, fully_pad_crypto_handshake_packets_, - next_transmission_type_, &frame)) { - // The only pending data in the packet is non-retransmittable frames. I'm - // assuming here that they won't occupy so much of the packet that a - // CRYPTO frame won't fit. - QUIC_BUG << "Failed to ConsumeCryptoData at level " << level; - return 0; - } - total_bytes_consumed += frame.crypto_frame->data_length; - - // TODO(ianswett): Move to having the creator flush itself when it's full. - packet_creator_.FlushCurrentPacket(); - } - - // Don't allow the handshake to be bundled with other retransmittable frames. - packet_creator_.FlushCurrentPacket(); - - return total_bytes_consumed; -} - -QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id, - size_t write_length, - QuicStreamOffset offset, - StreamSendingState state) { - if (packet_creator_.combine_generator_and_creator()) { - return packet_creator_.ConsumeData(id, write_length, offset, state); - } - QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when " - "generator tries to write stream data."; - bool has_handshake = - QuicUtils::IsCryptoStreamId(packet_creator_.transport_version(), id); - MaybeBundleAckOpportunistically(); - bool fin = state != NO_FIN; - QUIC_BUG_IF(has_handshake && fin) - << "Handshake packets should never send a fin"; - // To make reasoning about crypto frames easier, we don't combine them with - // other retransmittable frames in a single packet. - if (has_handshake && packet_creator_.HasPendingRetransmittableFrames()) { - packet_creator_.FlushCurrentPacket(); - } - - size_t total_bytes_consumed = 0; - bool fin_consumed = false; - - if (!packet_creator_.HasRoomForStreamFrame(id, offset, write_length)) { - packet_creator_.FlushCurrentPacket(); - } - - if (!fin && (write_length == 0)) { - QUIC_BUG << "Attempt to consume empty data without FIN."; - return QuicConsumedData(0, false); - } - // We determine if we can enter the fast path before executing - // the slow path loop. - bool run_fast_path = - !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() && - write_length - total_bytes_consumed > kMaxOutgoingPacketSize; - - while (!run_fast_path && delegate_->ShouldGeneratePacket( - HAS_RETRANSMITTABLE_DATA, - has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) { - QuicFrame frame; - bool needs_full_padding = - has_handshake && fully_pad_crypto_handshake_packets_; - - if (!packet_creator_.ConsumeDataToFillCurrentPacket( - id, write_length - total_bytes_consumed, - offset + total_bytes_consumed, fin, needs_full_padding, - next_transmission_type_, &frame)) { - // The creator is always flushed if there's not enough room for a new - // stream frame before ConsumeData, so ConsumeData should always succeed. - QUIC_BUG << "Failed to ConsumeData, stream:" << id; - return QuicConsumedData(0, false); - } - - // A stream frame is created and added. - size_t bytes_consumed = frame.stream_frame.data_length; - total_bytes_consumed += bytes_consumed; - fin_consumed = fin && total_bytes_consumed == write_length; - if (fin_consumed && state == FIN_AND_PADDING) { - AddRandomPadding(); - } - DCHECK(total_bytes_consumed == write_length || - (bytes_consumed > 0 && packet_creator_.HasPendingFrames())); - - if (total_bytes_consumed == write_length) { - // We're done writing the data. Exit the loop. - // We don't make this a precondition because we could have 0 bytes of data - // if we're simply writing a fin. - break; - } - // TODO(ianswett): Move to having the creator flush itself when it's full. - packet_creator_.FlushCurrentPacket(); - - run_fast_path = - !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() && - write_length - total_bytes_consumed > kMaxOutgoingPacketSize; - } - - if (run_fast_path) { - return ConsumeDataFastPath(id, write_length, offset, state != NO_FIN, - total_bytes_consumed); - } - - // Don't allow the handshake to be bundled with other retransmittable frames. - if (has_handshake) { - packet_creator_.FlushCurrentPacket(); - } - - return QuicConsumedData(total_bytes_consumed, fin_consumed); -} - -QuicConsumedData QuicPacketGenerator::ConsumeDataFastPath( - QuicStreamId id, - size_t write_length, - QuicStreamOffset offset, - bool fin, - size_t total_bytes_consumed) { - if (packet_creator_.combine_generator_and_creator()) { - return packet_creator_.ConsumeDataFastPath(id, write_length, offset, fin, - total_bytes_consumed); - } - DCHECK(!QuicUtils::IsCryptoStreamId(packet_creator_.transport_version(), id)); - - while (total_bytes_consumed < write_length && - delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, - NOT_HANDSHAKE)) { - // Serialize and encrypt the packet. - size_t bytes_consumed = 0; - packet_creator_.CreateAndSerializeStreamFrame( - id, write_length, total_bytes_consumed, offset + total_bytes_consumed, - fin, next_transmission_type_, &bytes_consumed); - total_bytes_consumed += bytes_consumed; - } - - return QuicConsumedData(total_bytes_consumed, - fin && (total_bytes_consumed == write_length)); -} - -void QuicPacketGenerator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) { - if (packet_creator_.combine_generator_and_creator()) { - packet_creator_.GenerateMtuDiscoveryPacket(target_mtu); - return; - } - // MTU discovery frames must be sent by themselves. - if (!packet_creator_.CanSetMaxPacketLength()) { - QUIC_BUG << "MTU discovery packets should only be sent when no other " - << "frames needs to be sent."; - return; - } - const QuicByteCount current_mtu = GetCurrentMaxPacketLength(); - - // The MTU discovery frame is allocated on the stack, since it is going to be - // serialized within this function. - QuicMtuDiscoveryFrame mtu_discovery_frame; - QuicFrame frame(mtu_discovery_frame); - - // Send the probe packet with the new length. - SetMaxPacketLength(target_mtu); - const bool success = - packet_creator_.AddPaddedSavedFrame(frame, next_transmission_type_); - packet_creator_.FlushCurrentPacket(); - // The only reason AddFrame can fail is that the packet is too full to fit in - // a ping. This is not possible for any sane MTU. - DCHECK(success); - - // Reset the packet length back. - SetMaxPacketLength(current_mtu); -} - -bool QuicPacketGenerator::PacketFlusherAttached() const { - if (packet_creator_.combine_generator_and_creator()) { - return packet_creator_.PacketFlusherAttached(); - } - return flusher_attached_; -} - -void QuicPacketGenerator::AttachPacketFlusher() { - if (packet_creator_.combine_generator_and_creator()) { - packet_creator_.AttachPacketFlusher(); - return; - } - flusher_attached_ = true; - if (!write_start_packet_number_.IsInitialized()) { - write_start_packet_number_ = packet_creator_.NextSendingPacketNumber(); - } -} - -void QuicPacketGenerator::Flush() { - if (packet_creator_.combine_generator_and_creator()) { - packet_creator_.Flush(); - return; - } - packet_creator_.FlushCurrentPacket(); - SendRemainingPendingPadding(); - flusher_attached_ = false; - if (GetQuicFlag(FLAGS_quic_export_server_num_packets_per_write_histogram)) { - if (!write_start_packet_number_.IsInitialized()) { - QUIC_BUG << "write_start_packet_number is not initialized"; - return; - } - QUIC_SERVER_HISTOGRAM_COUNTS( - "quic_server_num_written_packets_per_write", - packet_creator_.NextSendingPacketNumber() - write_start_packet_number_, - 1, 200, 50, "Number of QUIC packets written per write operation"); - } - write_start_packet_number_.Clear(); -} - -void QuicPacketGenerator::FlushAllQueuedFrames() { - packet_creator_.FlushCurrentPacket(); -} - -bool QuicPacketGenerator::HasPendingFrames() const { - return packet_creator_.HasPendingFrames(); -} - -void QuicPacketGenerator::StopSendingVersion() { - packet_creator_.StopSendingVersion(); -} - -void QuicPacketGenerator::SetDiversificationNonce( - const DiversificationNonce& nonce) { - packet_creator_.SetDiversificationNonce(nonce); -} - -QuicPacketNumber QuicPacketGenerator::packet_number() const { - return packet_creator_.packet_number(); -} - -QuicByteCount QuicPacketGenerator::GetCurrentMaxPacketLength() const { - return packet_creator_.max_packet_length(); -} - -void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length) { - DCHECK(packet_creator_.CanSetMaxPacketLength()); - packet_creator_.SetMaxPacketLength(length); -} - -std::unique_ptr<QuicEncryptedPacket> -QuicPacketGenerator::SerializeVersionNegotiationPacket( - bool ietf_quic, - bool use_length_prefix, - const ParsedQuicVersionVector& supported_versions) { - return packet_creator_.SerializeVersionNegotiationPacket( - ietf_quic, use_length_prefix, supported_versions); -} - -OwningSerializedPacketPointer -QuicPacketGenerator::SerializeConnectivityProbingPacket() { - return packet_creator_.SerializeConnectivityProbingPacket(); -} - -OwningSerializedPacketPointer -QuicPacketGenerator::SerializePathChallengeConnectivityProbingPacket( - QuicPathFrameBuffer* payload) { - return packet_creator_.SerializePathChallengeConnectivityProbingPacket( - payload); -} - -OwningSerializedPacketPointer -QuicPacketGenerator::SerializePathResponseConnectivityProbingPacket( - const QuicDeque<QuicPathFrameBuffer>& payloads, - const bool is_padded) { - return packet_creator_.SerializePathResponseConnectivityProbingPacket( - payloads, is_padded); -} - -void QuicPacketGenerator::UpdatePacketNumberLength( - QuicPacketNumber least_packet_awaited_by_peer, - QuicPacketCount max_packets_in_flight) { - return packet_creator_.UpdatePacketNumberLength(least_packet_awaited_by_peer, - max_packets_in_flight); -} - -void QuicPacketGenerator::SkipNPacketNumbers( - QuicPacketCount count, - QuicPacketNumber least_packet_awaited_by_peer, - QuicPacketCount max_packets_in_flight) { - packet_creator_.SkipNPacketNumbers(count, least_packet_awaited_by_peer, - max_packets_in_flight); -} - -void QuicPacketGenerator::SetServerConnectionIdLength(uint32_t length) { - if (packet_creator_.combine_generator_and_creator()) { - packet_creator_.SetServerConnectionIdLength(length); - return; - } - if (length == 0) { - packet_creator_.SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT); - } else { - packet_creator_.SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT); - } -} - -void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) { - packet_creator_.set_encryption_level(level); -} - -void QuicPacketGenerator::SetEncrypter( - EncryptionLevel level, - std::unique_ptr<QuicEncrypter> encrypter) { - packet_creator_.SetEncrypter(level, std::move(encrypter)); -} - -void QuicPacketGenerator::AddRandomPadding() { - if (packet_creator_.combine_generator_and_creator()) { - packet_creator_.AddRandomPadding(); - return; - } - packet_creator_.AddPendingPadding( - random_generator_->RandUint64() % kMaxNumRandomPaddingBytes + 1); -} - -void QuicPacketGenerator::SendRemainingPendingPadding() { - if (packet_creator_.combine_generator_and_creator()) { - packet_creator_.SendRemainingPendingPadding(); - return; - } - while ( - packet_creator_.pending_padding_bytes() > 0 && !HasPendingFrames() && - delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) { - packet_creator_.FlushCurrentPacket(); - } -} - -bool QuicPacketGenerator::HasRetransmittableFrames() const { - return packet_creator_.HasPendingRetransmittableFrames(); -} - -bool QuicPacketGenerator::HasPendingStreamFramesOfStream( - QuicStreamId id) const { - return packet_creator_.HasPendingStreamFramesOfStream(id); -} - -void QuicPacketGenerator::SetTransmissionType(TransmissionType type) { - if (packet_creator_.combine_generator_and_creator()) { - packet_creator_.SetTransmissionType(type); - return; - } - next_transmission_type_ = type; -} - -void QuicPacketGenerator::SetRetryToken(QuicStringPiece retry_token) { - packet_creator_.SetRetryToken(retry_token); -} - -MessageStatus QuicPacketGenerator::AddMessageFrame(QuicMessageId message_id, - QuicMemSliceSpan message) { - if (packet_creator_.combine_generator_and_creator()) { - return packet_creator_.AddMessageFrame(message_id, message); - } - QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when " - "generator tries to add message frame."; - MaybeBundleAckOpportunistically(); - const QuicByteCount message_length = message.total_length(); - if (message_length > GetCurrentLargestMessagePayload()) { - return MESSAGE_STATUS_TOO_LARGE; - } - if (!packet_creator_.HasRoomForMessageFrame(message_length)) { - packet_creator_.FlushCurrentPacket(); - } - QuicMessageFrame* frame = new QuicMessageFrame(message_id, message); - const bool success = - packet_creator_.AddSavedFrame(QuicFrame(frame), next_transmission_type_); - if (!success) { - QUIC_BUG << "Failed to send message " << message_id; - delete frame; - return MESSAGE_STATUS_INTERNAL_ERROR; - } - return MESSAGE_STATUS_SUCCESS; -} - -void QuicPacketGenerator::MaybeBundleAckOpportunistically() { - if (packet_creator_.combine_generator_and_creator()) { - packet_creator_.MaybeBundleAckOpportunistically(); - return; - } - if (packet_creator_.has_ack()) { - // Ack already queued, nothing to do. - return; - } - if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, - NOT_HANDSHAKE)) { - return; - } - const bool flushed = - FlushAckFrame(delegate_->MaybeBundleAckOpportunistically()); - DCHECK(flushed); -} - -bool QuicPacketGenerator::FlushAckFrame(const QuicFrames& frames) { - if (packet_creator_.combine_generator_and_creator()) { - return packet_creator_.FlushAckFrame(frames); - } - QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when " - "generator tries to send ACK frame."; - for (const auto& frame : frames) { - DCHECK(frame.type == ACK_FRAME || frame.type == STOP_WAITING_FRAME); - if (packet_creator_.HasPendingFrames()) { - if (packet_creator_.AddSavedFrame(frame, next_transmission_type_)) { - // There is pending frames and current frame fits. - continue; - } - } - DCHECK(!packet_creator_.HasPendingFrames()); - // There is no pending frames, consult the delegate whether a packet can be - // generated. - if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, - NOT_HANDSHAKE)) { - return false; - } - const bool success = - packet_creator_.AddSavedFrame(frame, next_transmission_type_); - QUIC_BUG_IF(!success) << "Failed to flush " << frame; - } - return true; -} - -QuicPacketLength QuicPacketGenerator::GetCurrentLargestMessagePayload() const { - return packet_creator_.GetCurrentLargestMessagePayload(); -} - -QuicPacketLength QuicPacketGenerator::GetGuaranteedLargestMessagePayload() - const { - return packet_creator_.GetGuaranteedLargestMessagePayload(); -} - -void QuicPacketGenerator::SetServerConnectionId( - QuicConnectionId server_connection_id) { - packet_creator_.SetServerConnectionId(server_connection_id); -} - -void QuicPacketGenerator::SetClientConnectionId( - QuicConnectionId client_connection_id) { - packet_creator_.SetClientConnectionId(client_connection_id); -} - -size_t QuicPacketGenerator::SerializeCoalescedPacket( - const QuicCoalescedPacket& coalesced, - char* buffer, - size_t buffer_len) { - return packet_creator_.SerializeCoalescedPacket(coalesced, buffer, - buffer_len); -} - -void QuicPacketGenerator::SetSoftMaxPacketLength(QuicByteCount length) { - packet_creator_.SetSoftMaxPacketLength(length); -} - -void QuicPacketGenerator::set_fully_pad_crypto_handshake_packets( - bool new_value) { - if (packet_creator_.combine_generator_and_creator()) { - packet_creator_.set_fully_pad_crypto_handshake_packets(new_value); - return; - } - fully_pad_crypto_handshake_packets_ = new_value; -} - -bool QuicPacketGenerator::fully_pad_crypto_handshake_packets() const { - if (packet_creator_.combine_generator_and_creator()) { - return packet_creator_.fully_pad_crypto_handshake_packets(); - } - return fully_pad_crypto_handshake_packets_; -} - -} // namespace quic
diff --git a/quic/core/quic_packet_generator.h b/quic/core/quic_packet_generator.h deleted file mode 100644 index efeed75..0000000 --- a/quic/core/quic_packet_generator.h +++ /dev/null
@@ -1,270 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Responsible for generating packets on behalf of a QuicConnection. -// Packets are serialized just-in-time. -// Ack and Feedback frames will be requested from the Connection -// just-in-time. When a packet needs to be sent, the Generator -// will serialize a packet and pass it to QuicConnection::SendOrQueuePacket() -// -// The Generator's mode of operation is controlled by two conditions: -// -// 1) Is the Delegate writable? -// -// If the Delegate is not writable, then no operations will cause -// a packet to be serialized. In particular: -// * SetShouldSendAck will simply record that an ack is to be sent. -// * AddControlFrame will enqueue the control frame. -// * ConsumeData will do nothing. -// -// If the Delegate is writable, then the behavior depends on the second -// condition: -// -// 2) Is the Generator in batch mode? -// -// If the Generator is NOT in batch mode, then each call to a write -// operation will serialize one or more packets. The contents will -// include any previous queued frames. If an ack should be sent -// but has not been sent, then the Delegate will be asked to create -// an Ack frame which will then be included in the packet. When -// the write call completes, the current packet will be serialized -// and sent to the Delegate, even if it is not full. -// -// If the Generator is in batch mode, then each write operation will -// add data to the "current" packet. When the current packet becomes -// full, it will be serialized and sent to the packet. When batch -// mode is ended via |FinishBatchOperations|, the current packet -// will be serialzied, even if it is not full. - -#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_GENERATOR_H_ -#define QUICHE_QUIC_CORE_QUIC_PACKET_GENERATOR_H_ - -#include <cstddef> -#include <cstdint> -#include <list> - -#include "net/third_party/quiche/src/quic/core/quic_packet_creator.h" -#include "net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h" -#include "net/third_party/quiche/src/quic/core/quic_types.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_export.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h" - -namespace quic { - -namespace test { -class QuicPacketGeneratorPeer; -} // namespace test - -class QUIC_EXPORT_PRIVATE QuicPacketGenerator { - public: - QuicPacketGenerator(QuicConnectionId server_connection_id, - QuicFramer* framer, - QuicRandom* random_generator, - QuicPacketCreator::DelegateInterface* delegate); - QuicPacketGenerator(const QuicPacketGenerator&) = delete; - QuicPacketGenerator& operator=(const QuicPacketGenerator&) = delete; - - ~QuicPacketGenerator(); - - // Consumes retransmittable control |frame|. Returns true if the frame is - // successfully consumed. Returns false otherwise. - bool ConsumeRetransmittableControlFrame(const QuicFrame& frame); - - // Given some data, may consume part or all of it and pass it to the - // packet creator to be serialized into packets. If not in batch - // mode, these packets will also be sent during this call. - // When |state| is FIN_AND_PADDING, random padding of size [1, 256] will be - // added after stream frames. If current constructed packet cannot - // accommodate, the padding will overflow to the next packet(s). - QuicConsumedData ConsumeData(QuicStreamId id, - size_t write_length, - QuicStreamOffset offset, - StreamSendingState state); - - // Consumes data for CRYPTO frames sent at |level| starting at |offset| for a - // total of |write_length| bytes, and returns the number of bytes consumed. - // The data is passed into the packet creator and serialized into one or more - // packets. - size_t ConsumeCryptoData(EncryptionLevel level, - size_t write_length, - QuicStreamOffset offset); - - // Sends as many data only packets as allowed by the send algorithm and the - // available iov. - // This path does not support padding, or bundling pending frames. - // In case we access this method from ConsumeData, total_bytes_consumed - // keeps track of how many bytes have already been consumed. - QuicConsumedData ConsumeDataFastPath(QuicStreamId id, - size_t write_length, - QuicStreamOffset offset, - bool fin, - size_t total_bytes_consumed); - - // Generates an MTU discovery packet of specified size. - void GenerateMtuDiscoveryPacket(QuicByteCount target_mtu); - - // Indicates whether packet flusher is currently attached. - bool PacketFlusherAttached() const; - // Attaches packet flusher. - void AttachPacketFlusher(); - // Flushes everything, including current open packet and pending padding. - void Flush(); - - // Flushes current open packet. - void FlushAllQueuedFrames(); - - // Returns true if there are frames pending to be serialized. - bool HasPendingFrames() const; - - // Makes the framer not serialize the protocol version in sent packets. - void StopSendingVersion(); - - // SetDiversificationNonce sets the nonce that will be sent in each public - // header of packets encrypted at the initial encryption level. Should only - // be called by servers. - void SetDiversificationNonce(const DiversificationNonce& nonce); - - // Creates a version negotiation packet which supports |supported_versions|. - std::unique_ptr<QuicEncryptedPacket> SerializeVersionNegotiationPacket( - bool ietf_quic, - bool use_length_prefix, - const ParsedQuicVersionVector& supported_versions); - - // Creates a connectivity probing packet. - OwningSerializedPacketPointer SerializeConnectivityProbingPacket(); - - // Create connectivity probing request and response packets using PATH - // CHALLENGE and PATH RESPONSE frames, respectively. - // SerializePathChallengeConnectivityProbingPacket will pad the packet to be - // MTU bytes long. - OwningSerializedPacketPointer SerializePathChallengeConnectivityProbingPacket( - QuicPathFrameBuffer* payload); - - // If |is_padded| is true then SerializePathResponseConnectivityProbingPacket - // will pad the packet to be MTU bytes long, else it will not pad the packet. - // |payloads| is cleared. - OwningSerializedPacketPointer SerializePathResponseConnectivityProbingPacket( - const QuicDeque<QuicPathFrameBuffer>& payloads, - const bool is_padded); - - // Update the packet number length to use in future packets as soon as it - // can be safely changed. - void UpdatePacketNumberLength(QuicPacketNumber least_packet_awaited_by_peer, - QuicPacketCount max_packets_in_flight); - - // Skip |count| packet numbers. - void SkipNPacketNumbers(QuicPacketCount count, - QuicPacketNumber least_packet_awaited_by_peer, - QuicPacketCount max_packets_in_flight); - - // Set the minimum number of bytes for the server connection id length; - void SetServerConnectionIdLength(uint32_t length); - - // Sets the encrypter to use for the encryption level. - void SetEncrypter(EncryptionLevel level, - std::unique_ptr<QuicEncrypter> encrypter); - - // Returns true if there are control frames or current constructed packet has - // pending retransmittable frames. - bool HasRetransmittableFrames() const; - - // Returns true if current constructed packet has pending stream frames for - // stream |id|. - bool HasPendingStreamFramesOfStream(QuicStreamId id) const; - - // Sets the encryption level that will be applied to new packets. - void set_encryption_level(EncryptionLevel level); - - // packet number of the last created packet, or 0 if no packets have been - // created. - QuicPacketNumber packet_number() const; - - // Returns the maximum length a current packet can actually have. - QuicByteCount GetCurrentMaxPacketLength() const; - - // Set maximum packet length in the creator immediately. May not be called - // when there are frames queued in the creator. - void SetMaxPacketLength(QuicByteCount length); - - // Set transmission type of next constructed packets. - void SetTransmissionType(TransmissionType type); - - // Sets the retry token to be sent over the wire in IETF Initial packets. - void SetRetryToken(QuicStringPiece retry_token); - - // Tries to add a message frame containing |message| and returns the status. - MessageStatus AddMessageFrame(QuicMessageId message_id, - QuicMemSliceSpan message); - - // Called to flush ACK and STOP_WAITING frames, returns false if the flush - // fails. - bool FlushAckFrame(const QuicFrames& frames); - - // Returns the largest payload that will fit into a single MESSAGE frame. - QuicPacketLength GetCurrentLargestMessagePayload() const; - QuicPacketLength GetGuaranteedLargestMessagePayload() const; - - // Update the server connection ID used in outgoing packets. - void SetServerConnectionId(QuicConnectionId server_connection_id); - - // Update the client connection ID used in outgoing packets. - void SetClientConnectionId(QuicConnectionId client_connection_id); - - // Serializes |coalesced| to provided |buffer|, returns coalesced packet - // length if serialization succeeds. Otherwise, returns 0. - size_t SerializeCoalescedPacket(const QuicCoalescedPacket& coalesced, - char* buffer, - size_t buffer_len); - - // Set a soft maximum packet length in the creator. If a packet cannot be - // successfully created, creator will remove the soft limit and use the actual - // max packet length. - void SetSoftMaxPacketLength(QuicByteCount length); - - void set_debug_delegate(QuicPacketCreator::DebugDelegate* debug_delegate) { - packet_creator_.set_debug_delegate(debug_delegate); - } - - void set_fully_pad_crypto_handshake_packets(bool new_value); - - bool fully_pad_crypto_handshake_packets() const; - - private: - friend class test::QuicPacketGeneratorPeer; - - // Adds a random amount of padding (between 1 to 256 bytes). - void AddRandomPadding(); - - // Sends remaining pending padding. - // Pending paddings should only be sent when there is nothing else to send. - void SendRemainingPendingPadding(); - - // Called when there is data to be sent, Retrieves updated ACK frame from - // delegate_ and flushes it. - void MaybeBundleAckOpportunistically(); - - QuicPacketCreator::DelegateInterface* delegate_; - - QuicPacketCreator packet_creator_; - - // Transmission type of the next serialized packet. - TransmissionType next_transmission_type_; - - // True if packet flusher is currently attached. - bool flusher_attached_; - - QuicRandom* random_generator_; - - // Whether crypto handshake packets should be fully padded. - bool fully_pad_crypto_handshake_packets_; - - // Packet number of the first packet of a write operation. This gets set - // when the out-most flusher attaches and gets cleared when the out-most - // flusher detaches. - QuicPacketNumber write_start_packet_number_; -}; - -} // namespace quic - -#endif // QUICHE_QUIC_CORE_QUIC_PACKET_GENERATOR_H_
diff --git a/quic/core/quic_packet_generator_test.cc b/quic/core/quic_packet_generator_test.cc deleted file mode 100644 index 7a7701e..0000000 --- a/quic/core/quic_packet_generator_test.cc +++ /dev/null
@@ -1,1511 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/third_party/quiche/src/quic/core/quic_packet_generator.h" - -#include <cstdint> -#include <memory> -#include <string> -#include <utility> - -#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" -#include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h" -#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" -#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h" -#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h" -#include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h" -#include "net/third_party/quiche/src/quic/core/quic_utils.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/third_party/quiche/src/quic/test_tools/mock_random.h" -#include "net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h" -#include "net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h" -#include "net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.h" -#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" -#include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h" -#include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h" - -using testing::_; -using testing::InSequence; -using testing::Return; -using testing::StrictMock; - -namespace quic { -namespace test { -namespace { - -class MockDelegate : public QuicPacketCreator::DelegateInterface { - public: - MockDelegate() {} - MockDelegate(const MockDelegate&) = delete; - MockDelegate& operator=(const MockDelegate&) = delete; - ~MockDelegate() override {} - - MOCK_METHOD2(ShouldGeneratePacket, - bool(HasRetransmittableData retransmittable, - IsHandshake handshake)); - MOCK_METHOD0(MaybeBundleAckOpportunistically, const QuicFrames()); - MOCK_METHOD0(GetPacketBuffer, char*()); - MOCK_METHOD1(OnSerializedPacket, void(SerializedPacket* packet)); - MOCK_METHOD2(OnUnrecoverableError, void(QuicErrorCode, const std::string&)); - - void SetCanWriteAnything() { - EXPECT_CALL(*this, ShouldGeneratePacket(_, _)).WillRepeatedly(Return(true)); - EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _)) - .WillRepeatedly(Return(true)); - } - - void SetCanNotWrite() { - EXPECT_CALL(*this, ShouldGeneratePacket(_, _)) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _)) - .WillRepeatedly(Return(false)); - } - - // Use this when only ack frames should be allowed to be written. - void SetCanWriteOnlyNonRetransmittable() { - EXPECT_CALL(*this, ShouldGeneratePacket(_, _)) - .WillRepeatedly(Return(false)); - EXPECT_CALL(*this, ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, _)) - .WillRepeatedly(Return(true)); - } -}; - -// Simple struct for describing the contents of a packet. -// Useful in conjunction with a SimpleQuicFrame for validating that a packet -// contains the expected frames. -struct PacketContents { - PacketContents() - : num_ack_frames(0), - num_connection_close_frames(0), - num_goaway_frames(0), - num_rst_stream_frames(0), - num_stop_waiting_frames(0), - num_stream_frames(0), - num_crypto_frames(0), - num_ping_frames(0), - num_mtu_discovery_frames(0), - num_padding_frames(0) {} - - size_t num_ack_frames; - size_t num_connection_close_frames; - size_t num_goaway_frames; - size_t num_rst_stream_frames; - size_t num_stop_waiting_frames; - size_t num_stream_frames; - size_t num_crypto_frames; - size_t num_ping_frames; - size_t num_mtu_discovery_frames; - size_t num_padding_frames; -}; - -} // namespace - -class TestPacketGenerator : public QuicPacketGenerator { - public: - TestPacketGenerator(QuicConnectionId connection_id, - QuicFramer* framer, - QuicRandom* random_generator, - QuicPacketCreator::DelegateInterface* delegate, - SimpleDataProducer* producer) - : QuicPacketGenerator(connection_id, framer, random_generator, delegate), - ack_frame_(InitAckFrame(1)), - delegate_(static_cast<MockDelegate*>(delegate)), - producer_(producer) {} - - bool ConsumeRetransmittableControlFrame(const QuicFrame& frame, - bool bundle_ack) { - if (!QuicPacketGeneratorPeer::GetPacketCreator(this)->has_ack()) { - QuicFrames frames; - if (bundle_ack) { - frames.push_back(QuicFrame(&ack_frame_)); - } - if (delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, - NOT_HANDSHAKE)) { - EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()) - .WillOnce(Return(frames)); - } - } - return QuicPacketGenerator::ConsumeRetransmittableControlFrame(frame); - } - - QuicConsumedData ConsumeDataFastPath(QuicStreamId id, - const struct iovec* iov, - int iov_count, - size_t total_length, - QuicStreamOffset offset, - bool fin) { - // Save data before data is consumed. - if (total_length > 0) { - producer_->SaveStreamData(id, iov, iov_count, 0, total_length); - } - return QuicPacketGenerator::ConsumeDataFastPath(id, total_length, offset, - fin, 0); - } - - QuicConsumedData ConsumeData(QuicStreamId id, - const struct iovec* iov, - int iov_count, - size_t total_length, - QuicStreamOffset offset, - StreamSendingState state) { - // Save data before data is consumed. - if (total_length > 0) { - producer_->SaveStreamData(id, iov, iov_count, 0, total_length); - } - if (!QuicPacketGeneratorPeer::GetPacketCreator(this)->has_ack() && - delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, - NOT_HANDSHAKE)) { - EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1); - } - return QuicPacketGenerator::ConsumeData(id, total_length, offset, state); - } - - MessageStatus AddMessageFrame(QuicMessageId message_id, - QuicMemSliceSpan message) { - if (!QuicPacketGeneratorPeer::GetPacketCreator(this)->has_ack() && - delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, - NOT_HANDSHAKE)) { - EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1); - } - return QuicPacketGenerator::AddMessageFrame(message_id, message); - } - - size_t ConsumeCryptoData(EncryptionLevel level, - QuicStringPiece data, - QuicStreamOffset offset) { - producer_->SaveCryptoData(level, offset, data); - if (!QuicPacketGeneratorPeer::GetPacketCreator(this)->has_ack() && - delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, - NOT_HANDSHAKE)) { - EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1); - } - return QuicPacketGenerator::ConsumeCryptoData(level, data.length(), offset); - } - - QuicAckFrame ack_frame_; - MockDelegate* delegate_; - SimpleDataProducer* producer_; -}; - -class QuicPacketGeneratorTest : public QuicTest { - public: - QuicPacketGeneratorTest() - : framer_(AllSupportedVersions(), - QuicTime::Zero(), - Perspective::IS_CLIENT, - kQuicDefaultConnectionIdLength), - generator_(TestConnectionId(), - &framer_, - &random_generator_, - &delegate_, - &producer_), - creator_(QuicPacketGeneratorPeer::GetPacketCreator(&generator_)), - ack_frame_(InitAckFrame(1)) { - EXPECT_CALL(delegate_, GetPacketBuffer()).WillRepeatedly(Return(nullptr)); - creator_->SetEncrypter( - ENCRYPTION_FORWARD_SECURE, - std::make_unique<NullEncrypter>(Perspective::IS_CLIENT)); - creator_->set_encryption_level(ENCRYPTION_FORWARD_SECURE); - framer_.set_data_producer(&producer_); - if (simple_framer_.framer()->version().KnowsWhichDecrypterToUse()) { - simple_framer_.framer()->InstallDecrypter( - ENCRYPTION_FORWARD_SECURE, - std::make_unique<NullDecrypter>(Perspective::IS_SERVER)); - } - generator_.AttachPacketFlusher(); - } - - ~QuicPacketGeneratorTest() override { - for (SerializedPacket& packet : packets_) { - delete[] packet.encrypted_buffer; - ClearSerializedPacket(&packet); - } - } - - void SavePacket(SerializedPacket* packet) { - packet->encrypted_buffer = CopyBuffer(*packet); - packets_.push_back(*packet); - packet->encrypted_buffer = nullptr; - packet->retransmittable_frames.clear(); - } - - protected: - QuicRstStreamFrame* CreateRstStreamFrame() { - return new QuicRstStreamFrame(1, 1, QUIC_STREAM_NO_ERROR, 0); - } - - QuicGoAwayFrame* CreateGoAwayFrame() { - return new QuicGoAwayFrame(2, QUIC_NO_ERROR, 1, std::string()); - } - - void CheckPacketContains(const PacketContents& contents, - size_t packet_index) { - ASSERT_GT(packets_.size(), packet_index); - const SerializedPacket& packet = packets_[packet_index]; - size_t num_retransmittable_frames = - contents.num_connection_close_frames + contents.num_goaway_frames + - contents.num_rst_stream_frames + contents.num_stream_frames + - contents.num_crypto_frames + contents.num_ping_frames; - size_t num_frames = - contents.num_ack_frames + contents.num_stop_waiting_frames + - contents.num_mtu_discovery_frames + contents.num_padding_frames + - num_retransmittable_frames; - - if (num_retransmittable_frames == 0) { - ASSERT_TRUE(packet.retransmittable_frames.empty()); - } else { - ASSERT_FALSE(packet.retransmittable_frames.empty()); - EXPECT_EQ(num_retransmittable_frames, - packet.retransmittable_frames.size()); - } - - ASSERT_TRUE(packet.encrypted_buffer != nullptr); - ASSERT_TRUE(simple_framer_.ProcessPacket( - QuicEncryptedPacket(packet.encrypted_buffer, packet.encrypted_length))); - size_t num_padding_frames = 0; - if (contents.num_padding_frames == 0) { - num_padding_frames = simple_framer_.padding_frames().size(); - } - EXPECT_EQ(num_frames + num_padding_frames, simple_framer_.num_frames()); - EXPECT_EQ(contents.num_ack_frames, simple_framer_.ack_frames().size()); - EXPECT_EQ(contents.num_connection_close_frames, - simple_framer_.connection_close_frames().size()); - EXPECT_EQ(contents.num_goaway_frames, - simple_framer_.goaway_frames().size()); - EXPECT_EQ(contents.num_rst_stream_frames, - simple_framer_.rst_stream_frames().size()); - EXPECT_EQ(contents.num_stream_frames, - simple_framer_.stream_frames().size()); - EXPECT_EQ(contents.num_crypto_frames, - simple_framer_.crypto_frames().size()); - EXPECT_EQ(contents.num_stop_waiting_frames, - simple_framer_.stop_waiting_frames().size()); - if (contents.num_padding_frames != 0) { - EXPECT_EQ(contents.num_padding_frames, - simple_framer_.padding_frames().size()); - } - - // From the receiver's perspective, MTU discovery frames are ping frames. - EXPECT_EQ(contents.num_ping_frames + contents.num_mtu_discovery_frames, - simple_framer_.ping_frames().size()); - } - - void CheckPacketHasSingleStreamFrame(size_t packet_index) { - ASSERT_GT(packets_.size(), packet_index); - const SerializedPacket& packet = packets_[packet_index]; - ASSERT_FALSE(packet.retransmittable_frames.empty()); - EXPECT_EQ(1u, packet.retransmittable_frames.size()); - ASSERT_TRUE(packet.encrypted_buffer != nullptr); - ASSERT_TRUE(simple_framer_.ProcessPacket( - QuicEncryptedPacket(packet.encrypted_buffer, packet.encrypted_length))); - EXPECT_EQ(1u, simple_framer_.num_frames()); - EXPECT_EQ(1u, simple_framer_.stream_frames().size()); - } - - void CheckAllPacketsHaveSingleStreamFrame() { - for (size_t i = 0; i < packets_.size(); i++) { - CheckPacketHasSingleStreamFrame(i); - } - } - - void CreateData(size_t len) { - data_array_.reset(new char[len]); - memset(data_array_.get(), '?', len); - iov_.iov_base = data_array_.get(); - iov_.iov_len = len; - } - - QuicFramer framer_; - MockRandom random_generator_; - StrictMock<MockDelegate> delegate_; - TestPacketGenerator generator_; - QuicPacketCreator* creator_; - SimpleQuicFramer simple_framer_; - std::vector<SerializedPacket> packets_; - QuicAckFrame ack_frame_; - struct iovec iov_; - SimpleBufferAllocator allocator_; - - private: - std::unique_ptr<char[]> data_array_; - SimpleDataProducer producer_; -}; - -class MockDebugDelegate : public QuicPacketCreator::DebugDelegate { - public: - MOCK_METHOD1(OnFrameAddedToPacket, void(const QuicFrame&)); -}; - -TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritable) { - delegate_.SetCanNotWrite(); - - QuicRstStreamFrame* rst_frame = CreateRstStreamFrame(); - const bool consumed = - generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), - /*bundle_ack=*/false); - EXPECT_FALSE(consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - delete rst_frame; -} - -TEST_F(QuicPacketGeneratorTest, AddControlFrame_OnlyAckWritable) { - delegate_.SetCanWriteOnlyNonRetransmittable(); - - QuicRstStreamFrame* rst_frame = CreateRstStreamFrame(); - const bool consumed = - generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), - /*bundle_ack=*/false); - EXPECT_FALSE(consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - delete rst_frame; -} - -TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldNotFlush) { - delegate_.SetCanWriteAnything(); - - generator_.ConsumeRetransmittableControlFrame( - QuicFrame(CreateRstStreamFrame()), - /*bundle_ack=*/false); - EXPECT_TRUE(generator_.HasPendingFrames()); - EXPECT_TRUE(generator_.HasRetransmittableFrames()); -} - -TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritableBatchThenFlush) { - delegate_.SetCanNotWrite(); - - QuicRstStreamFrame* rst_frame = CreateRstStreamFrame(); - const bool consumed = - generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), - /*bundle_ack=*/false); - EXPECT_FALSE(consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - delete rst_frame; -} - -TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldFlush) { - delegate_.SetCanWriteAnything(); - - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - - generator_.ConsumeRetransmittableControlFrame( - QuicFrame(CreateRstStreamFrame()), - /*bundle_ack=*/false); - generator_.Flush(); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - PacketContents contents; - contents.num_rst_stream_frames = 1; - CheckPacketContains(contents, 0); -} - -TEST_F(QuicPacketGeneratorTest, ConsumeCryptoData) { - delegate_.SetCanWriteAnything(); - - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - std::string data = "crypto data"; - size_t consumed_bytes = - generator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0); - generator_.Flush(); - EXPECT_EQ(data.length(), consumed_bytes); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - PacketContents contents; - contents.num_crypto_frames = 1; - contents.num_padding_frames = 1; - CheckPacketContains(contents, 0); -} - -TEST_F(QuicPacketGeneratorTest, ConsumeData_NotWritable) { - delegate_.SetCanNotWrite(); - - MakeIOVector("foo", &iov_); - QuicConsumedData consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); - EXPECT_EQ(0u, consumed.bytes_consumed); - EXPECT_FALSE(consumed.fin_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); -} - -TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldNotFlush) { - delegate_.SetCanWriteAnything(); - - MakeIOVector("foo", &iov_); - QuicConsumedData consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); - EXPECT_EQ(3u, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - EXPECT_TRUE(generator_.HasPendingFrames()); - EXPECT_TRUE(generator_.HasRetransmittableFrames()); -} - -TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldFlush) { - delegate_.SetCanWriteAnything(); - - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - MakeIOVector("foo", &iov_); - QuicConsumedData consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); - generator_.Flush(); - EXPECT_EQ(3u, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - PacketContents contents; - contents.num_stream_frames = 1; - CheckPacketContains(contents, 0); -} - -// Test the behavior of ConsumeData when the data consumed is for the crypto -// handshake stream. Ensure that the packet is always sent and padded even if -// the generator operates in batch mode. -TEST_F(QuicPacketGeneratorTest, ConsumeData_Handshake) { - delegate_.SetCanWriteAnything(); - - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - std::string data = "foo bar"; - MakeIOVector(data, &iov_); - size_t consumed_bytes = 0; - if (QuicVersionUsesCryptoFrames(framer_.transport_version())) { - consumed_bytes = generator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0); - } else { - consumed_bytes = - generator_ - .ConsumeData( - QuicUtils::GetCryptoStreamId(framer_.transport_version()), - &iov_, 1u, iov_.iov_len, 0, NO_FIN) - .bytes_consumed; - } - EXPECT_EQ(7u, consumed_bytes); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - PacketContents contents; - if (QuicVersionUsesCryptoFrames(framer_.transport_version())) { - contents.num_crypto_frames = 1; - } else { - contents.num_stream_frames = 1; - } - contents.num_padding_frames = 1; - CheckPacketContains(contents, 0); - - ASSERT_EQ(1u, packets_.size()); - ASSERT_EQ(kDefaultMaxPacketSize, generator_.GetCurrentMaxPacketLength()); - EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length); -} - -// Test the behavior of ConsumeData when the data is for the crypto handshake -// stream, but padding is disabled. -TEST_F(QuicPacketGeneratorTest, ConsumeData_Handshake_PaddingDisabled) { - generator_.set_fully_pad_crypto_handshake_packets(false); - - delegate_.SetCanWriteAnything(); - - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - std::string data = "foo"; - MakeIOVector(data, &iov_); - size_t bytes_consumed = 0; - if (QuicVersionUsesCryptoFrames(framer_.transport_version())) { - bytes_consumed = generator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0); - } else { - bytes_consumed = - generator_ - .ConsumeData( - QuicUtils::GetCryptoStreamId(framer_.transport_version()), - &iov_, 1u, iov_.iov_len, 0, NO_FIN) - .bytes_consumed; - } - EXPECT_EQ(3u, bytes_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - PacketContents contents; - if (QuicVersionUsesCryptoFrames(framer_.transport_version())) { - contents.num_crypto_frames = 1; - } else { - contents.num_stream_frames = 1; - } - contents.num_padding_frames = 0; - CheckPacketContains(contents, 0); - - ASSERT_EQ(1u, packets_.size()); - - // Packet is not fully padded, but we want to future packets to be larger. - ASSERT_EQ(kDefaultMaxPacketSize, generator_.GetCurrentMaxPacketLength()); - size_t expected_packet_length = 27; - if (QuicVersionUsesCryptoFrames(framer_.transport_version())) { - // The framing of CRYPTO frames is slightly different than that of stream - // frames, so the expected packet length differs slightly. - expected_packet_length = 28; - } - if (framer_.version().HasHeaderProtection()) { - expected_packet_length = 29; - } - EXPECT_EQ(expected_packet_length, packets_[0].encrypted_length); -} - -TEST_F(QuicPacketGeneratorTest, ConsumeData_EmptyData) { - delegate_.SetCanWriteAnything(); - - EXPECT_QUIC_BUG(generator_.ConsumeData( - QuicUtils::QuicUtils::GetFirstBidirectionalStreamId( - framer_.transport_version(), Perspective::IS_CLIENT), - nullptr, 0, 0, 0, NO_FIN), - "Attempt to consume empty data without FIN."); -} - -TEST_F(QuicPacketGeneratorTest, - ConsumeDataMultipleTimes_WritableAndShouldNotFlush) { - delegate_.SetCanWriteAnything(); - - MakeIOVector("foo", &iov_); - generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); - MakeIOVector("quux", &iov_); - QuicConsumedData consumed = - generator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 3, NO_FIN); - EXPECT_EQ(4u, consumed.bytes_consumed); - EXPECT_FALSE(consumed.fin_consumed); - EXPECT_TRUE(generator_.HasPendingFrames()); - EXPECT_TRUE(generator_.HasRetransmittableFrames()); -} - -TEST_F(QuicPacketGeneratorTest, ConsumeData_BatchOperations) { - delegate_.SetCanWriteAnything(); - - MakeIOVector("foo", &iov_); - generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, NO_FIN); - MakeIOVector("quux", &iov_); - QuicConsumedData consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 3, FIN); - EXPECT_EQ(4u, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - EXPECT_TRUE(generator_.HasPendingFrames()); - EXPECT_TRUE(generator_.HasRetransmittableFrames()); - - // Now both frames will be flushed out. - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - generator_.Flush(); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - PacketContents contents; - contents.num_stream_frames = - GetQuicReloadableFlag(quic_coalesce_stream_frames) ? 1 : 2; - CheckPacketContains(contents, 0); -} - -TEST_F(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) { - // Set the packet size be enough for two stream frames with 0 stream offset, - // but not enough for a stream frame of 0 offset and one with non-zero offset. - size_t length = - NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) + - GetPacketHeaderSize( - framer_.transport_version(), - creator_->GetDestinationConnectionIdLength(), - creator_->GetSourceConnectionIdLength(), - QuicPacketCreatorPeer::SendVersionInPacket(creator_), - !kIncludeDiversificationNonce, - QuicPacketCreatorPeer::GetPacketNumberLength(creator_), - QuicPacketCreatorPeer::GetRetryTokenLengthLength(creator_), 0, - QuicPacketCreatorPeer::GetLengthLength(creator_)) + - // Add an extra 3 bytes for the payload and 1 byte so - // BytesFree is larger than the GetMinStreamFrameSize. - QuicFramer::GetMinStreamFrameSize(framer_.transport_version(), 1, 0, - false, 3) + - 3 + - QuicFramer::GetMinStreamFrameSize(framer_.transport_version(), 1, 0, true, - 1) + - 1; - generator_.SetMaxPacketLength(length); - delegate_.SetCanWriteAnything(); - { - InSequence dummy; - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - } - // Queue enough data to prevent a stream frame with a non-zero offset from - // fitting. - MakeIOVector("foo", &iov_); - QuicConsumedData consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, NO_FIN); - EXPECT_EQ(3u, consumed.bytes_consumed); - EXPECT_FALSE(consumed.fin_consumed); - EXPECT_TRUE(generator_.HasPendingFrames()); - EXPECT_TRUE(generator_.HasRetransmittableFrames()); - - // This frame will not fit with the existing frame, causing the queued frame - // to be serialized, and it will be added to a new open packet. - MakeIOVector("bar", &iov_); - consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 3, FIN); - EXPECT_EQ(3u, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - EXPECT_TRUE(generator_.HasPendingFrames()); - EXPECT_TRUE(generator_.HasRetransmittableFrames()); - - creator_->FlushCurrentPacket(); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - PacketContents contents; - contents.num_stream_frames = 1; - CheckPacketContains(contents, 0); - CheckPacketContains(contents, 1); -} - -TEST_F(QuicPacketGeneratorTest, ConsumeDataFastPath) { - delegate_.SetCanWriteAnything(); - generator_.SetTransmissionType(LOSS_RETRANSMISSION); - - // Create a 10000 byte IOVector. - CreateData(10000); - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - QuicConsumedData consumed = generator_.ConsumeDataFastPath( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, true); - EXPECT_EQ(10000u, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - PacketContents contents; - contents.num_stream_frames = 1; - CheckPacketContains(contents, 0); - EXPECT_FALSE(packets_.empty()); - SerializedPacket packet = packets_.back(); - EXPECT_TRUE(!packet.retransmittable_frames.empty()); - EXPECT_EQ(LOSS_RETRANSMISSION, packet.transmission_type); - EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type); - const QuicStreamFrame& stream_frame = - packet.retransmittable_frames.front().stream_frame; - EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset); -} - -TEST_F(QuicPacketGeneratorTest, ConsumeDataLarge) { - delegate_.SetCanWriteAnything(); - - // Create a 10000 byte IOVector. - CreateData(10000); - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - QuicConsumedData consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); - EXPECT_EQ(10000u, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - PacketContents contents; - contents.num_stream_frames = 1; - CheckPacketContains(contents, 0); - EXPECT_FALSE(packets_.empty()); - SerializedPacket packet = packets_.back(); - EXPECT_TRUE(!packet.retransmittable_frames.empty()); - EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type); - const QuicStreamFrame& stream_frame = - packet.retransmittable_frames.front().stream_frame; - EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset); -} - -TEST_F(QuicPacketGeneratorTest, ConsumeDataLargeSendAckFalse) { - delegate_.SetCanNotWrite(); - - QuicRstStreamFrame* rst_frame = CreateRstStreamFrame(); - const bool success = - generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), - /*bundle_ack=*/true); - EXPECT_FALSE(success); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - delegate_.SetCanWriteAnything(); - - generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), - /*bundle_ack=*/false); - - // Create a 10000 byte IOVector. - CreateData(10000); - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - generator_.ConsumeRetransmittableControlFrame( - QuicFrame(CreateRstStreamFrame()), - /*bundle_ack=*/true); - QuicConsumedData consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); - generator_.Flush(); - - EXPECT_EQ(10000u, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - EXPECT_FALSE(packets_.empty()); - SerializedPacket packet = packets_.back(); - EXPECT_TRUE(!packet.retransmittable_frames.empty()); - EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type); - const QuicStreamFrame& stream_frame = - packet.retransmittable_frames.front().stream_frame; - EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset); -} - -TEST_F(QuicPacketGeneratorTest, ConsumeDataLargeSendAckTrue) { - if (VersionHasIetfInvariantHeader(framer_.transport_version())) { - return; - } - delegate_.SetCanNotWrite(); - delegate_.SetCanWriteAnything(); - - // Create a 10000 byte IOVector. - CreateData(10000); - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - QuicConsumedData consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); - generator_.Flush(); - - EXPECT_EQ(10000u, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - EXPECT_FALSE(packets_.empty()); - SerializedPacket packet = packets_.back(); - EXPECT_TRUE(!packet.retransmittable_frames.empty()); - EXPECT_EQ(STREAM_FRAME, packet.retransmittable_frames.front().type); - const QuicStreamFrame& stream_frame = - packet.retransmittable_frames.front().stream_frame; - EXPECT_EQ(10000u, stream_frame.data_length + stream_frame.offset); -} - -TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations) { - delegate_.SetCanNotWrite(); - - QuicRstStreamFrame* rst_frame = CreateRstStreamFrame(); - const bool consumed = - generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), - /*bundle_ack=*/true); - EXPECT_FALSE(consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - EXPECT_FALSE(generator_.HasPendingStreamFramesOfStream(3)); - - delegate_.SetCanWriteAnything(); - - EXPECT_TRUE( - generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), - /*bundle_ack=*/false)); - // Send some data and a control frame - MakeIOVector("quux", &iov_); - generator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 0, NO_FIN); - if (!VersionHasIetfQuicFrames(framer_.transport_version())) { - generator_.ConsumeRetransmittableControlFrame( - QuicFrame(CreateGoAwayFrame()), - /*bundle_ack=*/false); - } - EXPECT_TRUE(generator_.HasPendingStreamFramesOfStream(3)); - - // All five frames will be flushed out in a single packet. - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - generator_.Flush(); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - EXPECT_FALSE(generator_.HasPendingStreamFramesOfStream(3)); - - PacketContents contents; - // ACK will be flushed by connection. - contents.num_ack_frames = 0; - if (!VersionHasIetfQuicFrames(framer_.transport_version())) { - contents.num_goaway_frames = 1; - } else { - contents.num_goaway_frames = 0; - } - contents.num_rst_stream_frames = 1; - contents.num_stream_frames = 1; - CheckPacketContains(contents, 0); -} - -TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) { - delegate_.SetCanNotWrite(); - - QuicRstStreamFrame* rst_frame = CreateRstStreamFrame(); - const bool success = - generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), - /*bundle_ack=*/true); - EXPECT_FALSE(success); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - delegate_.SetCanWriteAnything(); - - { - InSequence dummy; - // All five frames will be flushed out in a single packet - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - } - EXPECT_TRUE( - generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame), - /*bundle_ack=*/false)); - // Send enough data to exceed one packet - size_t data_len = kDefaultMaxPacketSize + 100; - CreateData(data_len); - QuicConsumedData consumed = - generator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 0, FIN); - EXPECT_EQ(data_len, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - if (!VersionHasIetfQuicFrames(framer_.transport_version())) { - generator_.ConsumeRetransmittableControlFrame( - QuicFrame(CreateGoAwayFrame()), - /*bundle_ack=*/false); - } - - generator_.Flush(); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - // The first packet should have the queued data and part of the stream data. - PacketContents contents; - // ACK will be sent by connection. - contents.num_ack_frames = 0; - contents.num_rst_stream_frames = 1; - contents.num_stream_frames = 1; - CheckPacketContains(contents, 0); - - // The second should have the remainder of the stream data. - PacketContents contents2; - if (!VersionHasIetfQuicFrames(framer_.transport_version())) { - contents2.num_goaway_frames = 1; - } else { - contents2.num_goaway_frames = 0; - } - contents2.num_stream_frames = 1; - CheckPacketContains(contents2, 1); -} - -// Regression test of b/120493795. -TEST_F(QuicPacketGeneratorTest, PacketTransmissionType) { - delegate_.SetCanWriteAnything(); - - // The first ConsumeData will fill the packet without flush. - generator_.SetTransmissionType(LOSS_RETRANSMISSION); - - size_t data_len = 1324; - CreateData(data_len); - QuicStreamId stream1_id = QuicUtils::GetFirstBidirectionalStreamId( - framer_.transport_version(), Perspective::IS_CLIENT); - QuicConsumedData consumed = - generator_.ConsumeData(stream1_id, &iov_, 1u, iov_.iov_len, 0, NO_FIN); - EXPECT_EQ(data_len, consumed.bytes_consumed); - ASSERT_EQ(0u, creator_->BytesFree()) - << "Test setup failed: Please increase data_len to " - << data_len + creator_->BytesFree() << " bytes."; - - // The second ConsumeData can not be added to the packet and will flush. - generator_.SetTransmissionType(NOT_RETRANSMISSION); - - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - - QuicStreamId stream2_id = stream1_id + 4; - - consumed = - generator_.ConsumeData(stream2_id, &iov_, 1u, iov_.iov_len, 0, NO_FIN); - EXPECT_EQ(data_len, consumed.bytes_consumed); - - // Ensure the packet is successfully created. - ASSERT_EQ(1u, packets_.size()); - ASSERT_TRUE(packets_[0].encrypted_buffer); - ASSERT_EQ(1u, packets_[0].retransmittable_frames.size()); - EXPECT_EQ(stream1_id, - packets_[0].retransmittable_frames[0].stream_frame.stream_id); - - // Since the second frame was not added, the packet's transmission type - // should be the first frame's type. - EXPECT_EQ(packets_[0].transmission_type, LOSS_RETRANSMISSION); -} - -TEST_F(QuicPacketGeneratorTest, TestConnectionIdLength) { - QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); - generator_.SetServerConnectionIdLength(0); - EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID, - creator_->GetDestinationConnectionIdLength()); - - for (size_t i = 1; i < 10; i++) { - generator_.SetServerConnectionIdLength(i); - if (VersionHasIetfInvariantHeader(framer_.transport_version())) { - EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID, - creator_->GetDestinationConnectionIdLength()); - } else { - EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID, - creator_->GetDestinationConnectionIdLength()); - } - } -} - -// Test whether SetMaxPacketLength() works in the situation when the queue is -// empty, and we send three packets worth of data. -TEST_F(QuicPacketGeneratorTest, SetMaxPacketLength_Initial) { - delegate_.SetCanWriteAnything(); - - // Send enough data for three packets. - size_t data_len = 3 * kDefaultMaxPacketSize + 1; - size_t packet_len = kDefaultMaxPacketSize + 100; - ASSERT_LE(packet_len, kMaxOutgoingPacketSize); - generator_.SetMaxPacketLength(packet_len); - EXPECT_EQ(packet_len, generator_.GetCurrentMaxPacketLength()); - - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .Times(3) - .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - CreateData(data_len); - QuicConsumedData consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, - /*offset=*/0, FIN); - EXPECT_EQ(data_len, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - // We expect three packets, and first two of them have to be of packet_len - // size. We check multiple packets (instead of just one) because we want to - // ensure that |max_packet_length_| does not get changed incorrectly by the - // generator after first packet is serialized. - ASSERT_EQ(3u, packets_.size()); - EXPECT_EQ(packet_len, packets_[0].encrypted_length); - EXPECT_EQ(packet_len, packets_[1].encrypted_length); - CheckAllPacketsHaveSingleStreamFrame(); -} - -// Test whether SetMaxPacketLength() works in the situation when we first write -// data, then change packet size, then write data again. -TEST_F(QuicPacketGeneratorTest, SetMaxPacketLength_Middle) { - delegate_.SetCanWriteAnything(); - - // We send enough data to overflow default packet length, but not the altered - // one. - size_t data_len = kDefaultMaxPacketSize; - size_t packet_len = kDefaultMaxPacketSize + 100; - ASSERT_LE(packet_len, kMaxOutgoingPacketSize); - - // We expect to see three packets in total. - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .Times(3) - .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - - // Send two packets before packet size change. - CreateData(data_len); - QuicConsumedData consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, - /*offset=*/0, NO_FIN); - generator_.Flush(); - EXPECT_EQ(data_len, consumed.bytes_consumed); - EXPECT_FALSE(consumed.fin_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - // Make sure we already have two packets. - ASSERT_EQ(2u, packets_.size()); - - // Increase packet size. - generator_.SetMaxPacketLength(packet_len); - EXPECT_EQ(packet_len, generator_.GetCurrentMaxPacketLength()); - - // Send a packet after packet size change. - CreateData(data_len); - generator_.AttachPacketFlusher(); - consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, data_len, FIN); - generator_.Flush(); - EXPECT_EQ(data_len, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - // We expect first data chunk to get fragmented, but the second one to fit - // into a single packet. - ASSERT_EQ(3u, packets_.size()); - EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length); - EXPECT_LE(kDefaultMaxPacketSize, packets_[2].encrypted_length); - CheckAllPacketsHaveSingleStreamFrame(); -} - -// Test whether SetMaxPacketLength() works correctly when we force the change of -// the packet size in the middle of the batched packet. -TEST_F(QuicPacketGeneratorTest, SetMaxPacketLength_MidpacketFlush) { - delegate_.SetCanWriteAnything(); - - size_t first_write_len = kDefaultMaxPacketSize / 2; - size_t packet_len = kDefaultMaxPacketSize + 100; - size_t second_write_len = packet_len + 1; - ASSERT_LE(packet_len, kMaxOutgoingPacketSize); - - // First send half of the packet worth of data. We are in the batch mode, so - // should not cause packet serialization. - CreateData(first_write_len); - QuicConsumedData consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, - /*offset=*/0, NO_FIN); - EXPECT_EQ(first_write_len, consumed.bytes_consumed); - EXPECT_FALSE(consumed.fin_consumed); - EXPECT_TRUE(generator_.HasPendingFrames()); - EXPECT_TRUE(generator_.HasRetransmittableFrames()); - - // Make sure we have no packets so far. - ASSERT_EQ(0u, packets_.size()); - - // Expect a packet to be flushed. - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - - // Increase packet size after flushing all frames. - // Ensure it's immediately enacted. - generator_.FlushAllQueuedFrames(); - generator_.SetMaxPacketLength(packet_len); - EXPECT_EQ(packet_len, generator_.GetCurrentMaxPacketLength()); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - // We expect to see exactly one packet serialized after that, because we send - // a value somewhat exceeding new max packet size, and the tail data does not - // get serialized because we are still in the batch mode. - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - - // Send a more than a packet worth of data to the same stream. This should - // trigger serialization of one packet, and queue another one. - CreateData(second_write_len); - consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, - /*offset=*/first_write_len, FIN); - EXPECT_EQ(second_write_len, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - EXPECT_TRUE(generator_.HasPendingFrames()); - EXPECT_TRUE(generator_.HasRetransmittableFrames()); - - // We expect the first packet to be underfilled, and the second packet be up - // to the new max packet size. - ASSERT_EQ(2u, packets_.size()); - EXPECT_GT(kDefaultMaxPacketSize, packets_[0].encrypted_length); - EXPECT_EQ(packet_len, packets_[1].encrypted_length); - - CheckAllPacketsHaveSingleStreamFrame(); -} - -// Test sending a connectivity probing packet. -TEST_F(QuicPacketGeneratorTest, GenerateConnectivityProbingPacket) { - delegate_.SetCanWriteAnything(); - - OwningSerializedPacketPointer probing_packet; - if (VersionHasIetfQuicFrames(framer_.transport_version())) { - QuicPathFrameBuffer payload = { - {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}}; - probing_packet = - generator_.SerializePathChallengeConnectivityProbingPacket(&payload); - } else { - probing_packet = generator_.SerializeConnectivityProbingPacket(); - } - - ASSERT_TRUE(simple_framer_.ProcessPacket(QuicEncryptedPacket( - probing_packet->encrypted_buffer, probing_packet->encrypted_length))); - - EXPECT_EQ(2u, simple_framer_.num_frames()); - if (VersionHasIetfQuicFrames(framer_.transport_version())) { - EXPECT_EQ(1u, simple_framer_.path_challenge_frames().size()); - } else { - EXPECT_EQ(1u, simple_framer_.ping_frames().size()); - } - EXPECT_EQ(1u, simple_framer_.padding_frames().size()); -} - -// Test sending an MTU probe, without any surrounding data. -TEST_F(QuicPacketGeneratorTest, GenerateMtuDiscoveryPacket_Simple) { - delegate_.SetCanWriteAnything(); - - const size_t target_mtu = kDefaultMaxPacketSize + 100; - static_assert(target_mtu < kMaxOutgoingPacketSize, - "The MTU probe used by the test exceeds maximum packet size"); - - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - - generator_.GenerateMtuDiscoveryPacket(target_mtu); - - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - ASSERT_EQ(1u, packets_.size()); - EXPECT_EQ(target_mtu, packets_[0].encrypted_length); - - PacketContents contents; - contents.num_mtu_discovery_frames = 1; - contents.num_padding_frames = 1; - CheckPacketContains(contents, 0); -} - -// Test sending an MTU probe. Surround it with data, to ensure that it resets -// the MTU to the value before the probe was sent. -TEST_F(QuicPacketGeneratorTest, GenerateMtuDiscoveryPacket_SurroundedByData) { - delegate_.SetCanWriteAnything(); - - const size_t target_mtu = kDefaultMaxPacketSize + 100; - static_assert(target_mtu < kMaxOutgoingPacketSize, - "The MTU probe used by the test exceeds maximum packet size"); - - // Send enough data so it would always cause two packets to be sent. - const size_t data_len = target_mtu + 1; - - // Send a total of five packets: two packets before the probe, the probe - // itself, and two packets after the probe. - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .Times(5) - .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - - // Send data before the MTU probe. - CreateData(data_len); - QuicConsumedData consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, - /*offset=*/0, NO_FIN); - generator_.Flush(); - EXPECT_EQ(data_len, consumed.bytes_consumed); - EXPECT_FALSE(consumed.fin_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - // Send the MTU probe. - generator_.GenerateMtuDiscoveryPacket(target_mtu); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - // Send data after the MTU probe. - CreateData(data_len); - generator_.AttachPacketFlusher(); - consumed = generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, - /*offset=*/data_len, FIN); - generator_.Flush(); - EXPECT_EQ(data_len, consumed.bytes_consumed); - EXPECT_TRUE(consumed.fin_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - ASSERT_EQ(5u, packets_.size()); - EXPECT_EQ(kDefaultMaxPacketSize, packets_[0].encrypted_length); - EXPECT_EQ(target_mtu, packets_[2].encrypted_length); - EXPECT_EQ(kDefaultMaxPacketSize, packets_[3].encrypted_length); - - PacketContents probe_contents; - probe_contents.num_mtu_discovery_frames = 1; - probe_contents.num_padding_frames = 1; - - CheckPacketHasSingleStreamFrame(0); - CheckPacketHasSingleStreamFrame(1); - CheckPacketContains(probe_contents, 2); - CheckPacketHasSingleStreamFrame(3); - CheckPacketHasSingleStreamFrame(4); -} - -TEST_F(QuicPacketGeneratorTest, DontCrashOnInvalidStopWaiting) { - if (VersionSupportsMessageFrames(framer_.transport_version())) { - return; - } - // Test added to ensure the generator does not crash when an invalid frame is - // added. Because this is an indication of internal programming errors, - // DFATALs are expected. - // A 1 byte packet number length can't encode a gap of 1000. - QuicPacketCreatorPeer::SetPacketNumber(creator_, 1000); - - delegate_.SetCanNotWrite(); - delegate_.SetCanWriteAnything(); - - // This will not serialize any packets, because of the invalid frame. - EXPECT_CALL(delegate_, - OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET, _)); - EXPECT_QUIC_BUG(generator_.Flush(), - "packet_number_length 1 is too small " - "for least_unacked_delta: 1001"); -} - -// Regression test for b/31486443. -TEST_F(QuicPacketGeneratorTest, ConnectionCloseFrameLargerThanPacketSize) { - delegate_.SetCanWriteAnything(); - char buf[2000] = {}; - QuicStringPiece error_details(buf, 2000); - const QuicErrorCode kQuicErrorCode = QUIC_PACKET_WRITE_ERROR; - - QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame( - framer_.transport_version(), kQuicErrorCode, std::string(error_details), - /*transport_close_frame_type=*/0); - generator_.ConsumeRetransmittableControlFrame(QuicFrame(frame), - /*bundle_ack=*/false); - EXPECT_TRUE(generator_.HasPendingFrames()); - EXPECT_TRUE(generator_.HasRetransmittableFrames()); -} - -TEST_F(QuicPacketGeneratorTest, RandomPaddingAfterFinSingleStreamSinglePacket) { - const QuicByteCount kStreamFramePayloadSize = 100u; - char buf[kStreamFramePayloadSize] = {}; - const QuicStreamId kDataStreamId = 5; - // Set the packet size be enough for one stream frame with 0 stream offset and - // max size of random padding. - size_t length = - NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) + - GetPacketHeaderSize( - framer_.transport_version(), - creator_->GetDestinationConnectionIdLength(), - creator_->GetSourceConnectionIdLength(), - QuicPacketCreatorPeer::SendVersionInPacket(creator_), - !kIncludeDiversificationNonce, - QuicPacketCreatorPeer::GetPacketNumberLength(creator_), - QuicPacketCreatorPeer::GetRetryTokenLengthLength(creator_), 0, - QuicPacketCreatorPeer::GetLengthLength(creator_)) + - QuicFramer::GetMinStreamFrameSize( - framer_.transport_version(), kDataStreamId, 0, - /*last_frame_in_packet=*/false, - kStreamFramePayloadSize + kMaxNumRandomPaddingBytes) + - kStreamFramePayloadSize + kMaxNumRandomPaddingBytes; - generator_.SetMaxPacketLength(length); - delegate_.SetCanWriteAnything(); - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_); - QuicConsumedData consumed = generator_.ConsumeData( - kDataStreamId, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING); - generator_.Flush(); - EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - EXPECT_EQ(1u, packets_.size()); - PacketContents contents; - // The packet has both stream and padding frames. - contents.num_padding_frames = 1; - contents.num_stream_frames = 1; - CheckPacketContains(contents, 0); -} - -TEST_F(QuicPacketGeneratorTest, - RandomPaddingAfterFinSingleStreamMultiplePackets) { - const QuicByteCount kStreamFramePayloadSize = 100u; - char buf[kStreamFramePayloadSize] = {}; - const QuicStreamId kDataStreamId = 5; - // Set the packet size be enough for one stream frame with 0 stream offset + - // 1. One or more packets will accommodate. - size_t length = - NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) + - GetPacketHeaderSize( - framer_.transport_version(), - creator_->GetDestinationConnectionIdLength(), - creator_->GetSourceConnectionIdLength(), - QuicPacketCreatorPeer::SendVersionInPacket(creator_), - !kIncludeDiversificationNonce, - QuicPacketCreatorPeer::GetPacketNumberLength(creator_), - QuicPacketCreatorPeer::GetRetryTokenLengthLength(creator_), 0, - QuicPacketCreatorPeer::GetLengthLength(creator_)) + - QuicFramer::GetMinStreamFrameSize( - framer_.transport_version(), kDataStreamId, 0, - /*last_frame_in_packet=*/false, kStreamFramePayloadSize + 1) + - kStreamFramePayloadSize + 1; - generator_.SetMaxPacketLength(length); - delegate_.SetCanWriteAnything(); - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_); - QuicConsumedData consumed = generator_.ConsumeData( - kDataStreamId, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING); - generator_.Flush(); - EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - EXPECT_LE(1u, packets_.size()); - PacketContents contents; - // The first packet has both stream and padding frames. - contents.num_stream_frames = 1; - contents.num_padding_frames = 1; - CheckPacketContains(contents, 0); - - for (size_t i = 1; i < packets_.size(); ++i) { - // Following packets only have paddings. - contents.num_stream_frames = 0; - contents.num_padding_frames = 1; - CheckPacketContains(contents, i); - } -} - -TEST_F(QuicPacketGeneratorTest, - RandomPaddingAfterFinMultipleStreamsMultiplePackets) { - const QuicByteCount kStreamFramePayloadSize = 100u; - char buf[kStreamFramePayloadSize] = {}; - const QuicStreamId kDataStreamId1 = 5; - const QuicStreamId kDataStreamId2 = 6; - // Set the packet size be enough for first frame with 0 stream offset + second - // frame + 1 byte payload. two or more packets will accommodate. - size_t length = - NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) + - GetPacketHeaderSize( - framer_.transport_version(), - creator_->GetDestinationConnectionIdLength(), - creator_->GetSourceConnectionIdLength(), - QuicPacketCreatorPeer::SendVersionInPacket(creator_), - !kIncludeDiversificationNonce, - QuicPacketCreatorPeer::GetPacketNumberLength(creator_), - QuicPacketCreatorPeer::GetRetryTokenLengthLength(creator_), 0, - QuicPacketCreatorPeer::GetLengthLength(creator_)) + - QuicFramer::GetMinStreamFrameSize( - framer_.transport_version(), kDataStreamId1, 0, - /*last_frame_in_packet=*/false, kStreamFramePayloadSize) + - kStreamFramePayloadSize + - QuicFramer::GetMinStreamFrameSize(framer_.transport_version(), - kDataStreamId1, 0, - /*last_frame_in_packet=*/false, 1) + - 1; - generator_.SetMaxPacketLength(length); - delegate_.SetCanWriteAnything(); - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_); - QuicConsumedData consumed = generator_.ConsumeData( - kDataStreamId1, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING); - EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); - MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_); - consumed = generator_.ConsumeData(kDataStreamId2, &iov_, 1u, iov_.iov_len, 0, - FIN_AND_PADDING); - EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed); - generator_.Flush(); - EXPECT_FALSE(generator_.HasPendingFrames()); - EXPECT_FALSE(generator_.HasRetransmittableFrames()); - - EXPECT_LE(2u, packets_.size()); - PacketContents contents; - // The first packet has two stream frames. - contents.num_stream_frames = 2; - CheckPacketContains(contents, 0); - - // The second packet has one stream frame and padding frames. - contents.num_stream_frames = 1; - contents.num_padding_frames = 1; - CheckPacketContains(contents, 1); - - for (size_t i = 2; i < packets_.size(); ++i) { - // Following packets only have paddings. - contents.num_stream_frames = 0; - contents.num_padding_frames = 1; - CheckPacketContains(contents, i); - } -} - -TEST_F(QuicPacketGeneratorTest, AddMessageFrame) { - if (!VersionSupportsMessageFrames(framer_.transport_version())) { - return; - } - quic::QuicMemSliceStorage storage(nullptr, 0, nullptr, 0); - delegate_.SetCanWriteAnything(); - EXPECT_CALL(delegate_, OnSerializedPacket(_)) - .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket)); - - MakeIOVector("foo", &iov_); - generator_.ConsumeData( - QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(), - Perspective::IS_CLIENT), - &iov_, 1u, iov_.iov_len, 0, FIN); - EXPECT_EQ(MESSAGE_STATUS_SUCCESS, - generator_.AddMessageFrame( - 1, MakeSpan(&allocator_, "message", &storage))); - EXPECT_TRUE(generator_.HasPendingFrames()); - EXPECT_TRUE(generator_.HasRetransmittableFrames()); - - // Add a message which causes the flush of current packet. - EXPECT_EQ( - MESSAGE_STATUS_SUCCESS, - generator_.AddMessageFrame( - 2, MakeSpan( - &allocator_, - std::string(generator_.GetCurrentLargestMessagePayload(), 'a'), - &storage))); - EXPECT_TRUE(generator_.HasRetransmittableFrames()); - - // Failed to send messages which cannot fit into one packet. - EXPECT_EQ( - MESSAGE_STATUS_TOO_LARGE, - generator_.AddMessageFrame( - 3, - MakeSpan(&allocator_, - std::string( - generator_.GetCurrentLargestMessagePayload() + 10, 'a'), - &storage))); -} - -TEST_F(QuicPacketGeneratorTest, ConnectionId) { - generator_.SetServerConnectionId(TestConnectionId(0x1337)); - EXPECT_EQ(TestConnectionId(0x1337), creator_->GetDestinationConnectionId()); - EXPECT_EQ(EmptyQuicConnectionId(), creator_->GetSourceConnectionId()); - if (!framer_.version().SupportsClientConnectionIds()) { - return; - } - generator_.SetClientConnectionId(TestConnectionId(0x33)); - EXPECT_EQ(TestConnectionId(0x1337), creator_->GetDestinationConnectionId()); - EXPECT_EQ(TestConnectionId(0x33), creator_->GetSourceConnectionId()); -} - -} // namespace test -} // namespace quic
diff --git a/quic/quartc/quartc_packet_writer.cc b/quic/quartc/quartc_packet_writer.cc index 5ffb892..f67cc77 100644 --- a/quic/quartc/quartc_packet_writer.cc +++ b/quic/quartc/quartc_packet_writer.cc
@@ -29,7 +29,7 @@ static_cast<QuartcPerPacketOptions*>(options); if (quartc_options && quartc_options->connection) { info.packet_number = - quartc_options->connection->packet_generator().packet_number(); + quartc_options->connection->packet_creator().packet_number(); } int bytes_written = packet_transport_->Write(buffer, buf_len, info); if (bytes_written <= 0) {
diff --git a/quic/test_tools/quic_connection_peer.cc b/quic/test_tools/quic_connection_peer.cc index f2f1f2f..197514e 100644 --- a/quic/test_tools/quic_connection_peer.cc +++ b/quic/test_tools/quic_connection_peer.cc
@@ -9,7 +9,6 @@ #include "net/third_party/quiche/src/quic/core/quic_received_packet_manager.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h" -#include "net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h" namespace quic { @@ -39,14 +38,7 @@ // static QuicPacketCreator* QuicConnectionPeer::GetPacketCreator( QuicConnection* connection) { - return QuicPacketGeneratorPeer::GetPacketCreator( - &connection->packet_generator_); -} - -// static -QuicPacketGenerator* QuicConnectionPeer::GetPacketGenerator( - QuicConnection* connection) { - return &connection->packet_generator_; + return &connection->packet_creator_; } // static
diff --git a/quic/test_tools/quic_connection_peer.h b/quic/test_tools/quic_connection_peer.h index 04d7826..8eb1c40 100644 --- a/quic/test_tools/quic_connection_peer.h +++ b/quic/test_tools/quic_connection_peer.h
@@ -20,7 +20,6 @@ class QuicEncryptedPacket; class QuicFramer; class QuicPacketCreator; -class QuicPacketGenerator; class QuicPacketWriter; class QuicSentPacketManager; class SendAlgorithmInterface; @@ -43,8 +42,6 @@ static QuicPacketCreator* GetPacketCreator(QuicConnection* connection); - static QuicPacketGenerator* GetPacketGenerator(QuicConnection* connection); - static QuicSentPacketManager* GetSentPacketManager( QuicConnection* connection);
diff --git a/quic/test_tools/quic_packet_generator_peer.cc b/quic/test_tools/quic_packet_generator_peer.cc deleted file mode 100644 index 91a8752..0000000 --- a/quic/test_tools/quic_packet_generator_peer.cc +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.h" - -#include "net/third_party/quiche/src/quic/core/quic_packet_creator.h" -#include "net/third_party/quiche/src/quic/core/quic_packet_generator.h" - -namespace quic { -namespace test { - -// static -QuicPacketCreator* QuicPacketGeneratorPeer::GetPacketCreator( - QuicPacketGenerator* generator) { - return &generator->packet_creator_; -} - -} // namespace test -} // namespace quic
diff --git a/quic/test_tools/quic_packet_generator_peer.h b/quic/test_tools/quic_packet_generator_peer.h deleted file mode 100644 index 6941b08..0000000 --- a/quic/test_tools/quic_packet_generator_peer.h +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_GENERATOR_PEER_H_ -#define QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_GENERATOR_PEER_H_ - -#include "net/third_party/quiche/src/quic/core/quic_packets.h" - -namespace quic { - -class QuicPacketCreator; -class QuicPacketGenerator; - -namespace test { - -class QuicPacketGeneratorPeer { - public: - QuicPacketGeneratorPeer() = delete; - - static QuicPacketCreator* GetPacketCreator(QuicPacketGenerator* generator); -}; - -} // namespace test - -} // namespace quic - -#endif // QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_GENERATOR_PEER_H_