Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/quic_crypto_stream.h b/quic/core/quic_crypto_stream.h
new file mode 100644
index 0000000..d2a729e
--- /dev/null
+++ b/quic/core/quic_crypto_stream.h
@@ -0,0 +1,174 @@
+// 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.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
+#define QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
+
+#include <cstddef>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h"
+#include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_config.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/core/quic_stream.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.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"
+
+namespace quic {
+
+class QuicSession;
+
+// Crypto handshake messages in QUIC take place over a reserved stream with the
+// id 1.  Each endpoint (client and server) will allocate an instance of a
+// subclass of QuicCryptoStream to send and receive handshake messages.  (In the
+// normal 1-RTT handshake, the client will send a client hello, CHLO, message.
+// The server will receive this message and respond with a server hello message,
+// SHLO.  At this point both sides will have established a crypto context they
+// can use to send encrypted messages.
+//
+// For more details:
+// https://docs.google.com/document/d/1g5nIXAIkN_Y-7XJW5K45IblHd_L2f5LTaDUDwvZ5L6g/edit?usp=sharing
+class QUIC_EXPORT_PRIVATE QuicCryptoStream : public QuicStream {
+ public:
+  explicit QuicCryptoStream(QuicSession* session);
+  QuicCryptoStream(const QuicCryptoStream&) = delete;
+  QuicCryptoStream& operator=(const QuicCryptoStream&) = delete;
+
+  ~QuicCryptoStream() override;
+
+  // Returns the per-packet framing overhead associated with sending a
+  // handshake message for |version|.
+  static QuicByteCount CryptoMessageFramingOverhead(
+      QuicTransportVersion version,
+      QuicConnectionId connection_id);
+
+  // QuicStream implementation
+  void OnStreamFrame(const QuicStreamFrame& frame) override;
+  void OnDataAvailable() override;
+
+  // Called when a CRYPTO frame is received.
+  void OnCryptoFrame(const QuicCryptoFrame& frame);
+
+  // Called when a CRYPTO frame is ACKed.
+  bool OnCryptoFrameAcked(const QuicCryptoFrame& frame,
+                          QuicTime::Delta ack_delay_time);
+
+  // Performs key extraction to derive a new secret of |result_len| bytes
+  // dependent on |label|, |context|, and the stream's negotiated subkey secret.
+  // Returns false if the handshake has not been confirmed or the parameters are
+  // invalid (e.g. |label| contains null bytes); returns true on success.
+  bool ExportKeyingMaterial(QuicStringPiece label,
+                            QuicStringPiece context,
+                            size_t result_len,
+                            QuicString* result) const;
+
+  // Writes |data| to the QuicStream at level |level|.
+  virtual void WriteCryptoData(EncryptionLevel level, QuicStringPiece data);
+
+  // Returns true once an encrypter has been set for the connection.
+  virtual bool encryption_established() const = 0;
+
+  // Returns true once the crypto handshake has completed.
+  virtual bool handshake_confirmed() const = 0;
+
+  // Returns the parameters negotiated in the crypto handshake.
+  virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const = 0;
+
+  // Provides the message parser to use when data is received on this stream.
+  virtual CryptoMessageParser* crypto_message_parser() = 0;
+
+  // Called when the underlying QuicConnection has agreed upon a QUIC version to
+  // use.
+  virtual void OnSuccessfulVersionNegotiation(const ParsedQuicVersion& version);
+
+  // Called to cancel retransmission of unencrypted crypto stream data.
+  void NeuterUnencryptedStreamData();
+
+  // Override to record the encryption level of consumed data.
+  void OnStreamDataConsumed(size_t bytes_consumed) override;
+
+  // Returns whether there are any bytes pending retransmission in CRYPTO
+  // frames.
+  virtual bool HasPendingCryptoRetransmission();
+
+  // Writes any pending CRYPTO frame retransmissions.
+  void WritePendingCryptoRetransmission();
+
+  // Override to retransmit lost crypto data with the appropriate encryption
+  // level.
+  void WritePendingRetransmission() override;
+
+  // Override to send unacked crypto data with the appropriate encryption level.
+  bool RetransmitStreamData(QuicStreamOffset offset,
+                            QuicByteCount data_length,
+                            bool fin) override;
+
+  // Returns the number of bytes of handshake data that have been received from
+  // the peer in either CRYPTO or STREAM frames.
+  uint64_t crypto_bytes_read() const;
+
+  // Returns the number of bytes of handshake data that have been received from
+  // the peer in CRYPTO frames at a particular encryption level.
+  QuicByteCount BytesReadOnLevel(EncryptionLevel level) const;
+
+  // Writes |data_length| of data of a crypto frame to |writer|. The data
+  // written is from the send buffer for encryption level |level| and starts at
+  // |offset|.
+  bool WriteCryptoFrame(EncryptionLevel level,
+                        QuicStreamOffset offset,
+                        QuicByteCount data_length,
+                        QuicDataWriter* writer);
+
+  // Called when data from a CRYPTO frame is considered lost. The lost data is
+  // identified by the encryption level, offset, and length in |crypto_frame|.
+  void OnCryptoFrameLost(QuicCryptoFrame* crypto_frame);
+
+  // Called to retransmit any outstanding data in the range indicated by the
+  // encryption level, offset, and length in |crypto_frame|.
+  void RetransmitData(QuicCryptoFrame* crypto_frame);
+
+  // Returns true if any portion of the data at encryption level |level|
+  // starting at |offset| for |length| bytes is outstanding.
+  bool IsFrameOutstanding(EncryptionLevel level,
+                          size_t offset,
+                          size_t length) const;
+
+  // Returns true if the crypto handshake is still waiting for acks of sent
+  // data, and false if all data has been acked.
+  bool IsWaitingForAcks() const;
+
+ private:
+  // Data sent and received in CRYPTO frames is sent at multiple encryption
+  // levels. Some of the state for the single logical crypto stream is split
+  // across encryption levels, and a CryptoSubstream is used to manage that
+  // state for a particular encryption level.
+  struct CryptoSubstream {
+    CryptoSubstream(QuicCryptoStream* crypto_stream, EncryptionLevel);
+
+    QuicStreamSequencer sequencer;
+    QuicStreamSendBuffer send_buffer;
+  };
+
+  // Helper method for OnDataAvailable. Calls CryptoMessageParser::ProcessInput
+  // with the data available in |sequencer| and |level|, and marks the data
+  // passed to ProcessInput as consumed.
+  void OnDataAvailableInSequencer(QuicStreamSequencer* sequencer,
+                                  EncryptionLevel level);
+
+  // Consumed data according to encryption levels.
+  // TODO(fayang): This is not needed once switching from QUIC crypto to
+  // TLS 1.3, which never encrypts crypto data.
+  QuicIntervalSet<QuicStreamOffset> bytes_consumed_[NUM_ENCRYPTION_LEVELS];
+
+  // Keeps state for data sent/received in CRYPTO frames at each encryption
+  // level.
+  CryptoSubstream substreams_[NUM_ENCRYPTION_LEVELS];
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_