Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/quic_stream.h b/quic/core/quic_stream.h
new file mode 100644
index 0000000..fe0a794
--- /dev/null
+++ b/quic/core/quic_stream.h
@@ -0,0 +1,541 @@
+// 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.
+
+// The base class for client/server QUIC streams.
+
+// It does not contain the entire interface needed by an application to interact
+// with a QUIC stream.  Some parts of the interface must be obtained by
+// accessing the owning session object.  A subclass of QuicStream
+// connects the object and the application that generates and consumes the data
+// of the stream.
+
+// The QuicStream object has a dependent QuicStreamSequencer object,
+// which is given the stream frames as they arrive, and provides stream data in
+// order by invoking ProcessRawData().
+
+#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_H_
+#define QUICHE_QUIC_CORE_QUIC_STREAM_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <list>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/quic_flow_controller.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/core/quic_stream_send_buffer.h"
+#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer.h"
+#include "net/third_party/quiche/src/quic/core/quic_types.h"
+#include "net/third_party/quiche/src/quic/core/session_notifier_interface.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"
+#include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
+
+namespace quic {
+
+namespace test {
+class QuicStreamPeer;
+}  // namespace test
+
+class QuicSession;
+class QuicStream;
+
+// Buffers frames for a stream until the first byte of that frame arrives.
+class QUIC_EXPORT_PRIVATE PendingStream
+    : public QuicStreamSequencer::StreamInterface {
+ public:
+  PendingStream(QuicStreamId id, QuicSession* session);
+  PendingStream(const PendingStream&) = delete;
+  PendingStream(PendingStream&&) = default;
+  ~PendingStream() override = default;
+
+  // QuicStreamSequencer::StreamInterface
+  void OnDataAvailable() override;
+  void OnFinRead() override;
+  void AddBytesConsumed(QuicByteCount bytes) override;
+  void Reset(QuicRstStreamErrorCode error) override;
+  void CloseConnectionWithDetails(QuicErrorCode error,
+                                  const QuicString& details) override;
+  QuicStreamId id() const override;
+  const QuicSocketAddress& PeerAddressOfLatestPacket() const override;
+
+  // Buffers the contents of |frame|. Frame must have a non-zero offset.
+  // If the data violates flow control, the connection will be closed.
+  void OnStreamFrame(const QuicStreamFrame& frame);
+
+  // Stores the final byte offset from |frame|.
+  // If the final offset violates flow control, the connection will be closed.
+  void OnRstStreamFrame(const QuicRstStreamFrame& frame);
+
+  // Returns the number of bytes read on this stream.
+  uint64_t stream_bytes_read() { return stream_bytes_read_; }
+
+ private:
+  friend class QuicStream;
+
+  bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);
+
+  // ID of this stream.
+  QuicStreamId id_;
+
+  // Session which owns this.
+  QuicSession* session_;
+
+  // Bytes read refers to payload bytes only: they do not include framing,
+  // encryption overhead etc.
+  uint64_t stream_bytes_read_;
+
+  // True if a frame containing a fin has been received.
+  bool fin_received_;
+
+  // Connection-level flow controller. Owned by the session.
+  QuicFlowController* connection_flow_controller_;
+  // Stream-level flow controller.
+  QuicFlowController flow_controller_;
+  // Stores the buffered frames.
+  QuicStreamSequencer sequencer_;
+};
+
+class QUIC_EXPORT_PRIVATE QuicStream
+    : public QuicStreamSequencer::StreamInterface {
+ public:
+  // This is somewhat arbitrary.  It's possible, but unlikely, we will either
+  // fail to set a priority client-side, or cancel a stream before stripping the
+  // priority from the wire server-side.  In either case, start out with a
+  // priority in the middle.
+  static const spdy::SpdyPriority kDefaultPriority = 3;
+  static_assert(kDefaultPriority ==
+                    (spdy::kV3LowestPriority + spdy::kV3HighestPriority) / 2,
+                "Unexpected value of kDefaultPriority");
+
+  // Creates a new stream with stream_id |id| associated with |session|. If
+  // |is_static| is true, then the stream will be given precedence
+  // over other streams when determing what streams should write next.
+  // |type| indicates whether the stream is bidirectional, read unidirectional
+  // or write unidirectional.
+  // TODO(fayang): Remove |type| when IETF stream ID numbering fully kicks in.
+  QuicStream(QuicStreamId id,
+             QuicSession* session,
+             bool is_static,
+             StreamType type);
+  QuicStream(PendingStream pending, StreamType type);
+  QuicStream(const QuicStream&) = delete;
+  QuicStream& operator=(const QuicStream&) = delete;
+
+  virtual ~QuicStream();
+
+  // Not in use currently.
+  void SetFromConfig();
+
+  // QuicStreamSequencer::StreamInterface implementation.
+  QuicStreamId id() const override { return id_; }
+  // Called by the stream subclass after it has consumed the final incoming
+  // data.
+  void OnFinRead() override;
+
+  // Called by the subclass or the sequencer to reset the stream from this
+  // end.
+  void Reset(QuicRstStreamErrorCode error) override;
+
+  // Called by the subclass or the sequencer to close the entire connection from
+  // this end.
+  void CloseConnectionWithDetails(QuicErrorCode error,
+                                  const QuicString& details) override;
+
+  // Called by the stream sequencer as bytes are consumed from the buffer.
+  // If the receive window has dropped below the threshold, then send a
+  // WINDOW_UPDATE frame.
+  void AddBytesConsumed(QuicByteCount bytes) override;
+
+  // Get peer IP of the lastest packet which connection is dealing/delt with.
+  const QuicSocketAddress& PeerAddressOfLatestPacket() const override;
+
+  // Called by the session when a (potentially duplicate) stream frame has been
+  // received for this stream.
+  virtual void OnStreamFrame(const QuicStreamFrame& frame);
+
+  // Called by the session when the connection becomes writeable to allow the
+  // stream to write any pending data.
+  virtual void OnCanWrite();
+
+  // Called by the session just before the object is destroyed.
+  // The object should not be accessed after OnClose is called.
+  // Sends a RST_STREAM with code QUIC_RST_ACKNOWLEDGEMENT if neither a FIN nor
+  // a RST_STREAM has been sent.
+  virtual void OnClose();
+
+  // Called by the session when the endpoint receives a RST_STREAM from the
+  // peer.
+  virtual void OnStreamReset(const QuicRstStreamFrame& frame);
+
+  // Called by the session when the endpoint receives or sends a connection
+  // close, and should immediately close the stream.
+  virtual void OnConnectionClosed(QuicErrorCode error,
+                                  ConnectionCloseSource source);
+
+  spdy::SpdyPriority priority() const;
+
+  // Sets priority_ to priority.  This should only be called before bytes are
+  // written to the server.
+  void SetPriority(spdy::SpdyPriority priority);
+
+  // Returns true if this stream is still waiting for acks of sent data.
+  // This will return false if all data has been acked, or if the stream
+  // is no longer interested in data being acked (which happens when
+  // a stream is reset because of an error).
+  bool IsWaitingForAcks() const;
+
+  // Number of bytes available to read.
+  size_t ReadableBytes() const;
+
+  QuicRstStreamErrorCode stream_error() const { return stream_error_; }
+  QuicErrorCode connection_error() const { return connection_error_; }
+
+  bool reading_stopped() const {
+    return sequencer_.ignore_read_data() || read_side_closed_;
+  }
+  bool write_side_closed() const { return write_side_closed_; }
+
+  bool rst_received() const { return rst_received_; }
+  bool rst_sent() const { return rst_sent_; }
+  bool fin_received() const { return fin_received_; }
+  bool fin_sent() const { return fin_sent_; }
+  bool fin_outstanding() const { return fin_outstanding_; }
+  bool fin_lost() const { return fin_lost_; }
+
+  uint64_t BufferedDataBytes() const;
+
+  uint64_t stream_bytes_read() const { return stream_bytes_read_; }
+  uint64_t stream_bytes_written() const;
+
+  size_t busy_counter() const { return busy_counter_; }
+  void set_busy_counter(size_t busy_counter) { busy_counter_ = busy_counter; }
+
+  void set_fin_sent(bool fin_sent) { fin_sent_ = fin_sent; }
+  void set_fin_received(bool fin_received) { fin_received_ = fin_received; }
+  void set_rst_sent(bool rst_sent) { rst_sent_ = rst_sent; }
+
+  void set_rst_received(bool rst_received) { rst_received_ = rst_received; }
+  void set_stream_error(QuicRstStreamErrorCode error) { stream_error_ = error; }
+
+  // Adjust the flow control window according to new offset in |frame|.
+  virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
+
+  int num_frames_received() const;
+  int num_duplicate_frames_received() const;
+
+  QuicFlowController* flow_controller() { return &flow_controller_; }
+
+  // Called when endpoint receives a frame which could increase the highest
+  // offset.
+  // Returns true if the highest offset did increase.
+  bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);
+  // Called when bytes are sent to the peer.
+  void AddBytesSent(QuicByteCount bytes);
+
+  // Updates the flow controller's send window offset and calls OnCanWrite if
+  // it was blocked before.
+  void UpdateSendWindowOffset(QuicStreamOffset new_offset);
+
+  // Returns true if the stream has received either a RST_STREAM or a FIN -
+  // either of which gives a definitive number of bytes which the peer has
+  // sent. If this is not true on deletion of the stream object, the session
+  // must keep track of the stream's byte offset until a definitive final value
+  // arrives.
+  bool HasFinalReceivedByteOffset() const {
+    return fin_received_ || rst_received_;
+  }
+
+  // Returns true if the stream has queued data waiting to write.
+  bool HasBufferedData() const;
+
+  // Returns the version of QUIC being used for this stream.
+  QuicTransportVersion transport_version() const;
+
+  // Returns the crypto handshake protocol that was used on this stream's
+  // connection.
+  HandshakeProtocol handshake_protocol() const;
+
+  // Sets the sequencer to consume all incoming data itself and not call
+  // OnDataAvailable().
+  // When the FIN is received, the stream will be notified automatically (via
+  // OnFinRead()) (which may happen during the call of StopReading()).
+  // TODO(dworley): There should be machinery to send a RST_STREAM/NO_ERROR and
+  // stop sending stream-level flow-control updates when this end sends FIN.
+  virtual void StopReading();
+
+  // Sends as much of 'data' to the connection as the connection will consume,
+  // and then buffers any remaining data in queued_data_.
+  // If fin is true: if it is immediately passed on to the session,
+  // write_side_closed() becomes true, otherwise fin_buffered_ becomes true.
+  void WriteOrBufferData(
+      QuicStringPiece data,
+      bool fin,
+      QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
+
+  // Adds random padding after the fin is consumed for this stream.
+  void AddRandomPaddingAfterFin();
+
+  // Write |data_length| of data starts at |offset| from send buffer.
+  bool WriteStreamData(QuicStreamOffset offset,
+                       QuicByteCount data_length,
+                       QuicDataWriter* writer);
+
+  // Called when data [offset, offset + data_length) is acked. |fin_acked|
+  // indicates whether the fin is acked. Returns true and updates
+  // |newly_acked_length| if any new stream data (including fin) gets acked.
+  virtual bool OnStreamFrameAcked(QuicStreamOffset offset,
+                                  QuicByteCount data_length,
+                                  bool fin_acked,
+                                  QuicTime::Delta ack_delay_time,
+                                  QuicByteCount* newly_acked_length);
+
+  // Called when data [offset, offset + data_length) was retransmitted.
+  // |fin_retransmitted| indicates whether fin was retransmitted.
+  virtual void OnStreamFrameRetransmitted(QuicStreamOffset offset,
+                                          QuicByteCount data_length,
+                                          bool fin_retransmitted);
+
+  // Called when data [offset, offset + data_length) is considered as lost.
+  // |fin_lost| indicates whether the fin is considered as lost.
+  virtual void OnStreamFrameLost(QuicStreamOffset offset,
+                                 QuicByteCount data_length,
+                                 bool fin_lost);
+
+  // Called to retransmit outstanding portion in data [offset, offset +
+  // data_length) and |fin|. Returns true if all data gets retransmitted.
+  virtual bool RetransmitStreamData(QuicStreamOffset offset,
+                                    QuicByteCount data_length,
+                                    bool fin);
+
+  // Sets deadline of this stream to be now + |ttl|, returns true if the setting
+  // succeeds.
+  bool MaybeSetTtl(QuicTime::Delta ttl);
+
+  // Same as WritevData except data is provided in reference counted memory so
+  // that data copy is avoided.
+  QuicConsumedData WriteMemSlices(QuicMemSliceSpan span, bool fin);
+
+  // Returns true if any stream data is lost (including fin) and needs to be
+  // retransmitted.
+  virtual bool HasPendingRetransmission() const;
+
+  // Returns true if any portion of data [offset, offset + data_length) is
+  // outstanding or fin is outstanding (if |fin| is true). Returns false
+  // otherwise.
+  bool IsStreamFrameOutstanding(QuicStreamOffset offset,
+                                QuicByteCount data_length,
+                                bool fin) const;
+
+  StreamType type() const { return type_; }
+
+  // Creates and sends a STOP_SENDING frame.  This can be called regardless of
+  // the version that has been negotiated.  If not IETF QUIC/Version 99 then the
+  // method is a noop, relieving the application of the necessity of
+  // understanding the connection's QUIC version and knowing whether it can call
+  // this method or not.
+  void SendStopSending(uint16_t code);
+
+  // Invoked when QUIC receives a STOP_SENDING frame for this stream, informing
+  // the application that the peer has sent a STOP_SENDING. The default
+  // implementation is a noop. Is to be overridden by the application-specific
+  // QuicStream class.
+  virtual void OnStopSending(uint16_t code);
+
+  // Close the write side of the socket.  Further writes will fail.
+  // Can be called by the subclass or internally.
+  // Does not send a FIN.  May cause the stream to be closed.
+  virtual void CloseWriteSide();
+
+ protected:
+  // Sends as many bytes in the first |count| buffers of |iov| to the connection
+  // as the connection will consume. If FIN is consumed, the write side is
+  // immediately closed.
+  // Returns the number of bytes consumed by the connection.
+  // Please note: Returned consumed data is the amount of data saved in send
+  // buffer. The data is not necessarily consumed by the connection. So write
+  // side is closed when FIN is sent.
+  // TODO(fayang): Let WritevData return boolean.
+  QuicConsumedData WritevData(const struct iovec* iov, int iov_count, bool fin);
+
+  // Allows override of the session level writev, for the force HOL
+  // blocking experiment.
+  virtual QuicConsumedData WritevDataInner(size_t write_length,
+                                           QuicStreamOffset offset,
+                                           bool fin);
+
+  // Close the read side of the socket.  May cause the stream to be closed.
+  // Subclasses and consumers should use StopReading to terminate reading early
+  // if expecting a FIN. Can be used directly by subclasses if not expecting a
+  // FIN.
+  void CloseReadSide();
+
+  // Called when data of [offset, offset + data_length] is buffered in send
+  // buffer.
+  virtual void OnDataBuffered(
+      QuicStreamOffset offset,
+      QuicByteCount data_length,
+      const QuicReferenceCountedPointer<QuicAckListenerInterface>&
+          ack_listener) {}
+
+  // True if buffered data in send buffer is below buffered_data_threshold_.
+  bool CanWriteNewData() const;
+
+  // True if buffered data in send buffer is still below
+  // buffered_data_threshold_ even after writing |length| bytes.
+  bool CanWriteNewDataAfterData(QuicByteCount length) const;
+
+  // Called when upper layer can write new data.
+  virtual void OnCanWriteNewData() {}
+
+  // Called when |bytes_consumed| bytes has been consumed.
+  virtual void OnStreamDataConsumed(size_t bytes_consumed);
+
+  // Writes pending retransmissions if any.
+  virtual void WritePendingRetransmission();
+
+  // This is called when stream tries to retransmit data after deadline_. Make
+  // this virtual so that subclasses can implement their own logics.
+  virtual void OnDeadlinePassed();
+
+  bool fin_buffered() const { return fin_buffered_; }
+
+  const QuicSession* session() const { return session_; }
+  QuicSession* session() { return session_; }
+
+  const QuicStreamSequencer* sequencer() const { return &sequencer_; }
+  QuicStreamSequencer* sequencer() { return &sequencer_; }
+
+  void DisableConnectionFlowControlForThisStream() {
+    stream_contributes_to_connection_flow_control_ = false;
+  }
+
+  const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const;
+
+  const QuicStreamSendBuffer& send_buffer() const { return send_buffer_; }
+
+  QuicStreamSendBuffer& send_buffer() { return send_buffer_; }
+
+ private:
+  friend class test::QuicStreamPeer;
+  friend class QuicStreamUtils;
+
+  QuicStream(QuicStreamId id,
+             QuicSession* session,
+             QuicStreamSequencer sequencer,
+             bool is_static,
+             StreamType type,
+             uint64_t stream_bytes_read,
+             bool fin_received,
+             QuicFlowController flow_controller,
+             QuicFlowController* connection_flow_controller);
+
+  // Subclasses and consumers should use reading_stopped.
+  bool read_side_closed() const { return read_side_closed_; }
+
+  // Calls MaybeSendBlocked on the stream's flow controller and the connection
+  // level flow controller.  If the stream is flow control blocked by the
+  // connection-level flow controller but not by the stream-level flow
+  // controller, marks this stream as connection-level write blocked.
+  void MaybeSendBlocked();
+
+  // Write buffered data in send buffer. TODO(fayang): Consider combine
+  // WriteOrBufferData, Writev and WriteBufferedData.
+  void WriteBufferedData();
+
+  // Returns true if deadline_ has passed.
+  bool HasDeadlinePassed() const;
+
+  QuicStreamSequencer sequencer_;
+  QuicStreamId id_;
+  // Pointer to the owning QuicSession object.
+  QuicSession* session_;
+  // The priority of the stream, once parsed.
+  spdy::SpdyPriority priority_;
+  // Bytes read refers to payload bytes only: they do not include framing,
+  // encryption overhead etc.
+  uint64_t stream_bytes_read_;
+
+  // Stream error code received from a RstStreamFrame or error code sent by the
+  // visitor or sequencer in the RstStreamFrame.
+  QuicRstStreamErrorCode stream_error_;
+  // Connection error code due to which the stream was closed. |stream_error_|
+  // is set to |QUIC_STREAM_CONNECTION_ERROR| when this happens and consumers
+  // should check |connection_error_|.
+  QuicErrorCode connection_error_;
+
+  // True if the read side is closed and further frames should be rejected.
+  bool read_side_closed_;
+  // True if the write side is closed, and further writes should fail.
+  bool write_side_closed_;
+
+  // True if the subclass has written a FIN with WriteOrBufferData, but it was
+  // buffered in queued_data_ rather than being sent to the session.
+  bool fin_buffered_;
+  // True if a FIN has been sent to the session.
+  bool fin_sent_;
+  // True if a FIN is waiting to be acked.
+  bool fin_outstanding_;
+  // True if a FIN is lost.
+  bool fin_lost_;
+
+  // True if this stream has received (and the sequencer has accepted) a
+  // StreamFrame with the FIN set.
+  bool fin_received_;
+
+  // True if an RST_STREAM has been sent to the session.
+  // In combination with fin_sent_, used to ensure that a FIN and/or a
+  // RST_STREAM is always sent to terminate the stream.
+  bool rst_sent_;
+
+  // True if this stream has received a RST_STREAM frame.
+  bool rst_received_;
+
+  // Tracks if the session this stream is running under was created by a
+  // server or a client.
+  Perspective perspective_;
+
+  QuicFlowController flow_controller_;
+
+  // The connection level flow controller. Not owned.
+  QuicFlowController* connection_flow_controller_;
+
+  // Special streams, such as the crypto and headers streams, do not respect
+  // connection level flow control limits (but are stream level flow control
+  // limited).
+  bool stream_contributes_to_connection_flow_control_;
+
+  // A counter incremented when OnCanWrite() is called and no progress is made.
+  // For debugging only.
+  size_t busy_counter_;
+
+  // Indicates whether paddings will be added after the fin is consumed for this
+  // stream.
+  bool add_random_padding_after_fin_;
+
+  // Send buffer of this stream. Send buffer is cleaned up when data gets acked
+  // or discarded.
+  QuicStreamSendBuffer send_buffer_;
+
+  // Latched value of FLAGS_quic_buffered_data_threshold.
+  const QuicByteCount buffered_data_threshold_;
+
+  // If true, then this stream has precedence over other streams for write
+  // scheduling.
+  const bool is_static_;
+
+  // If initialized, reset this stream at this deadline.
+  QuicTime deadline_;
+
+  // Indicates whether this stream is bidirectional, read unidirectional or
+  // write unidirectional.
+  const StreamType type_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_H_