Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/quic_packet_generator.h b/quic/core/quic_packet_generator.h
new file mode 100644
index 0000000..3a951f0
--- /dev/null
+++ b/quic/core/quic_packet_generator.h
@@ -0,0 +1,313 @@
+// 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.  Control frames are queued.
+// 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 "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/quic_packet_creator.h"
+#include "net/third_party/quiche/src/quic/core/quic_pending_retransmission.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:
+  class QUIC_EXPORT_PRIVATE DelegateInterface
+      : public QuicPacketCreator::DelegateInterface {
+   public:
+    ~DelegateInterface() override {}
+    // Consults delegate whether a packet should be generated.
+    virtual bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
+                                      IsHandshake handshake) = 0;
+    // Called when there is data to be sent. Retrieves updated ACK frame from
+    // the delegate.
+    virtual const QuicFrames MaybeBundleAckOpportunistically() = 0;
+    // TODO(fayang): Remove these two interfaces when deprecating
+    // quic_deprecate_ack_bundling_mode.
+    virtual const QuicFrame GetUpdatedAckFrame() = 0;
+    virtual void PopulateStopWaitingFrame(
+        QuicStopWaitingFrame* stop_waiting) = 0;
+  };
+
+  QuicPacketGenerator(QuicConnectionId connection_id,
+                      QuicFramer* framer,
+                      QuicRandom* random_generator,
+                      DelegateInterface* delegate);
+  QuicPacketGenerator(const QuicPacketGenerator&) = delete;
+  QuicPacketGenerator& operator=(const QuicPacketGenerator&) = delete;
+
+  ~QuicPacketGenerator();
+
+  // Indicates that an ACK frame should be sent.
+  // If |also_send_stop_waiting| is true, then it also indicates that a
+  // STOP_WAITING frame should be sent as well.
+  // The contents of the frame(s) will be generated via a call to the delegate
+  // CreateAckFrame() when the packet is serialized.
+  void SetShouldSendAck(bool also_send_stop_waiting);
+
+  void AddControlFrame(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 all queued frames and pending padding.
+  void Flush();
+
+  // Flushes all queued frames, even frames which are not sendable.
+  void FlushAllQueuedFrames();
+
+  bool HasQueuedFrames() const;
+
+  // Whether the pending packet has no frames in it at the moment.
+  bool IsPendingPacketEmpty() 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,
+      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);
+
+  // Re-serializes frames with the original packet's packet number length.
+  // Used for retransmitting packets to ensure they aren't too long.
+  void ReserializeAllFrames(const QuicPendingRetransmission& retransmission,
+                            char* buffer,
+                            size_t buffer_len);
+
+  // 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);
+
+  // Set the minimum number of bytes for the connection id length;
+  void SetConnectionIdLength(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);
+
+  // Allow/Disallow setting transmission type of next constructed packets.
+  void SetCanSetTransmissionType(bool can_set_transmission_type);
+
+  // 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 GetLargestMessagePayload() const;
+
+  void set_debug_delegate(QuicPacketCreator::DebugDelegate* debug_delegate) {
+    packet_creator_.set_debug_delegate(debug_delegate);
+  }
+
+  bool should_send_ack() const { return should_send_ack_; }
+
+  void set_fully_pad_crypto_hadshake_packets(bool new_value) {
+    fully_pad_crypto_handshake_packets_ = new_value;
+  }
+
+  bool fully_pad_crypto_handshake_packets() const {
+    return fully_pad_crypto_handshake_packets_;
+  }
+
+  bool deprecate_ack_bundling_mode() const {
+    return deprecate_ack_bundling_mode_;
+  }
+
+ private:
+  friend class test::QuicPacketGeneratorPeer;
+
+  void SendQueuedFrames(bool flush);
+
+  // Test to see if we have pending ack, or control frames.
+  bool HasPendingFrames() const;
+  // Returns true if addition of a pending frame (which might be
+  // retransmittable) would still allow the resulting packet to be sent now.
+  bool CanSendWithNextPendingFrameAddition() const;
+  // Add exactly one pending frame, preferring ack frames over control frames.
+  // Returns true if a pending frame is successfully added.
+  // Returns false and flushes current open packet if the pending frame cannot
+  // fit into current open packet.
+  bool AddNextPendingFrame();
+
+  // 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();
+
+  DelegateInterface* delegate_;
+
+  QuicPacketCreator packet_creator_;
+  QuicFrames queued_control_frames_;
+
+  // Transmission type of the next serialized packet.
+  TransmissionType next_transmission_type_;
+
+  // True if packet flusher is currently attached.
+  bool flusher_attached_;
+
+  // Flags to indicate the need for just-in-time construction of a frame.
+  // TODO(fayang): Remove these two booleans when deprecating
+  // quic_deprecate_ack_bundling_mode.
+  bool should_send_ack_;
+  bool should_send_stop_waiting_;
+  // If we put a non-retransmittable frame in this packet, then we have to hold
+  // a reference to it until we flush (and serialize it). Retransmittable frames
+  // are referenced elsewhere so that they can later be (optionally)
+  // retransmitted.
+  // TODO(fayang): Remove this when deprecating
+  // quic_deprecate_ack_bundling_mode.
+  QuicStopWaitingFrame pending_stop_waiting_frame_;
+
+  QuicRandom* random_generator_;
+
+  // Whether crypto handshake packets should be fully padded.
+  bool fully_pad_crypto_handshake_packets_;
+
+  // Latched value of quic_deprecate_ack_bundling_mode.
+  const bool deprecate_ack_bundling_mode_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_GENERATOR_H_